Leetcode热题100_128.最长连续序列
Leetcode热题100_128.最长连续序列
题目要求
-
给定一个未排序的整数数组 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
示例 3:
输入:nums = [1,0,1,2]
输出:3
哈希表
- 对于数组中存在的连续序列,为了统计每个连续序列的长度,我们希望直接定位到每个连续序列的起点,从起点开始遍历每个连续序列,从而获得长度。

1 | class Solution { |
- 时间复杂度:
- 将数组元素添加到哈希表中需要 O(n) 的时间。
- 遍历哈希表中的每个元素需要 O(n) 的时间。
- while循环在最坏的情况下可能需要执行n次。然而,由于集合查找操作的时间复杂度是O(1),这个while循环并不会显著增加总体的时间复杂度。
- 所以总体时间复杂度为 O(n)。
- 空间复杂度:
- 哈希表中存储了数组中的所有元素,空间复杂度为 O(n)。
关于时间复杂度
结论先给出来:时间复杂度是 O(n)。
不是 O(n²),原因有点反直觉,但一拆开就很清晰。🧠
这里的 n 指的是 数组长度(或者说 set 中元素个数的数量级)。
先把代码拆成两个阶段看。
第一阶段是把数组放进 HashSet:
1 | for(int num : nums) { |
HashSet.add() 的平均复杂度是 O(1)(底层是哈希表)。
循环 n 次,所以这一段是:
1 | O(n) |
到这里没什么悬念。
真正让人疑惑的是第二部分:
1 | for(int num : set) { |
乍一看会觉得:
1 | 外层 for: n |
但实际不是,因为 while 不会被重复执行很多次。
关键逻辑是这一句:
1 | if (set.contains(num - 1)) continue; |
这句话的意思是:
只有连续序列的起点才会进入 while
例如:
1 | set = {1,2,3,4,5} |
遍历过程:
1 | num=1 → 0 不存在 → 起点 → while 扫描 1,2,3,4,5 |
注意一个关键事实:
每个元素只会被 while 扫描一次。
while 访问的序列:
1 | 1 → 2 → 3 → 4 → 5 |
之后再遍历到 2,3,4,5 时:
1 | 直接 continue |
不会再次进入 while。
从“元素被访问的次数”角度看更清晰:
每个数字最多经历:
for循环访问一次while扩展访问一次
所以总访问次数是:
1 | O(n) + O(n) |
也就是:
1 | O(n) |
再看一个极端情况:
1 | nums = [100,4,200,1,3,2] |
set:
1 | {1,2,3,4,100,200} |
运行过程:
1 | 1 → while 扫描 1,2,3,4 |
所有 while 加起来访问:
1 | 1,2,3,4,100,200 |
还是 每个元素一次。
所以完整复杂度:
1 | 构建 set O(n) |
总复杂度:
1 | O(n) |
空间复杂度:
1 | O(n) |
(因为 HashSet 存了所有元素)
