最长连续序列

128. 最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

1
2
3
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4

示例 2:

1
2
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

提示:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109

我们考虑枚举数组中每个数 x,考虑以其为起点,不断尝试匹配 x+1,x+2,⋯ 是否存在,假设最长匹配到了 x+y,那么以 x 为起点的最长连续序列即为 x,x+1,x+2,⋯ ,x+y,其长度为 y+1,我们不断枚举并更新答案即可。

对于匹配的过程,暴力的方法是 O(n)遍历数组去看是否存在这个数,但其实更高效的方法是用一个哈希表存储数组中的数,这样查看一个数是否存在即能优化至 O(1)的时间复杂度。

仅仅是这样我们的算法时间复杂度最坏情况下还是会达到O(n^2)(即外层需要枚举 O(n)个数,内层需要暴力匹配 O(n) 次),无法满足题目的要求。但仔细分析这个过程,我们会发现其中执行了很多不必要的枚举,如果已知有一个 x,x+1,x+2,⋯ ,x+y的连续序列,而我们却重新从 x+1,x+2或者是 x+y处开始尝试匹配,那么得到的结果肯定不会优于枚举 x 为起点的答案,因此我们在外层循环的时候碰到这种情况跳过即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public int longestConsecutive(int[] nums) {
Set<Integer> set = new HashSet<>();
for(int x : nums){
set.add(x);
}
int longest = 0;
for(int x : nums){
if(set.contains(x-1)) continue; //已经检验过了,不需要重复检验
int curLong = 1;
while(set.contains(x+1)){
x = x + 1;
curLong ++;
}
longest = Math.max(curLong, longest);

}
return longest;
}
}

最长连续序列
http://example.com/2023/03/25/算法/哈希表/9. 最长连续序列/
作者
PALE13
发布于
2023年3月25日
许可协议