给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
示例 2:
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
解法一:哈希表存放右边界
class Solution {//哈希表记录当前数的右边界public int longestConsecutive(int[] nums) {Map<Integer,Integer> map = new HashMap<>();//先存入自身的值for (int num : nums) map.put(num,num);int res = 0;for (int num : nums) {if (map.containsKey(num)) {int right = map.get(num);while (map.containsKey(right + 1)) {//这步很重要,当right+1存在时,我们就把right的键值对删除,后面就可以判断right的key值不存在跳出循环,保证每个数只被遍历一次保证Onmap.remove(right);right = map.get(right+1);}res = Math.max(res,right - num + 1);map.put(num,right);}}return res;}}
解法二:哈希表存放连续区间长度
class Solution {//哈希表记录当前数的连续区间长度public int longestConsecutive(int[] nums) {Map<Integer,Integer> map = new HashMap<>();int res = 0;for (int num : nums) {//只有当哈希表里面没有的数我们才统计if (!map.containsKey(num)) {//左连续区间和右连续区间,因为num未存在哈希表中,所以key=num-1,它的value表示区间只能是[num-value,num-1],同理key=num+1,它的value表示区间只能是[num+1,num+value];int left = map.getOrDefault(num-1,0);int right = map.getOrDefault(num+1,0);int curLen = left + right + 1;res = Math.max(res,curLen);//标记num,可以put任意值,如果[left,num]会put num,成为右边界,[num,right],会put num,成为左边界,否则则会成为中间值[left,right];map.put(num,-1);map.put(num-left,curLen);map.put(num+right,curLen);}}return res;}}
解法三:并查集
class Solution {Map<Integer,Integer> map = new HashMap<>();private int find(int x) {if (!map.containsKey(x)) return 0x3f3f3f3f;//路径压缩if (map.get(x) != x) map.put(x,find(map.get(x)));x = map.get(x);return x;}private void union(int x, int y) {int a = find(x);int b = find(y);if (a == b) return;map.put(a,b);}public int longestConsecutive(int[] nums) {for (int num : nums) map.put(num,num);for (int num : nums) {if (find(num+1) != 0x3f3f3f3f)union(num,num+1);}int res = 0;for (int num : nums)res = Math.max(res,find(num) - num + 1);return res;}}
