mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
686 字
2 分钟
最长连续序列
2026-06-16

题目描述#

题目链接

输入#

一个未排序的整数数组 nums

输出#

数字连续的最长序列的长度(不要求序列元素在原数组中连续)

约束条件#

  1. 0 <= nums.length <= 10^5
  2. -10^9 <= nums[i] <= 10^9
  3. 时间复杂度需要为 O(n)O(n)

示例1#

input: nums = [100,4,200,1,3,2]
output: 4

解释:最长数字连续序列是 [1, 2, 3, 4],长度为 4。

示例2#

input: nums = [0,3,7,2,5,8,4,6,0,1]
output: 9

解释:最长数字连续序列是 [0, 1, 2, 3, 4, 5, 6, 7, 8],长度为 9。

示例3#

input: nums = [1,0,1,2]
output: 3

解释:最长数字连续序列是 [0, 1, 2],长度为 3。

解题思路#

题目要求找出数组中数值连续的最长序列长度,这里的”连续”指的是数字本身相差 1,并不要求它们在原数组中下标相邻。

很容易想到先排序再从头扫描统计连续段长度,比如 [100,4,200,1,3,2] 排序后变成 [1,2,3,4,100,200],扫一遍就能数出最长段。但排序至少需要 O(nlogn)O(n \log n),题目明确要求 O(n)O(n),此路不通。

既然不能排序,又要快速判断某个数是否在集合中,我们在前两题学过的哈希集合就派上用场了——set 的查询是 O(1)O(1) 的,还能顺便去重。

一个自然的想法是:把 nums 转成 set,对每个数 x 不断检查 x+1x+2……是否在集合里,统计长度。但这样会有大量重复计算——比如序列 [1,2,3,4],从 1 往上数一遍,从 2 又往上数一遍,最坏会退化到 O(n2)O(n^2)

怎么避免重复?关键思路是:每条连续序列只需要统计一次。常见做法是从序列的左端点入手——若 x - 1 在集合中,说明 x 不是开头,直接跳过;否则从 x 向右扩展统计长度。

我们的做法是对称的:从序列的右端点入手。遍历集合中的每个 x,若 x + 1 还在集合里,说明 x 不是某段连续序列的最大值,跳过;只有当 x + 1 不存在时,x 才是一段连续序列的右端点。

确认 x 是右端点后,向左”顺藤摸瓜”:令 t = x,不断 t -= 1,直到 t 不在集合中为止。此时 t 恰好落在连续段左端点的左边一位,因此这段序列的长度就是 x - t

nums = [100,4,200,1,3,2] 为例,去重后集合为 {1,2,3,4,100,200}

  • 123 的右邻 +1 都在集合中,跳过
  • 遇到 45 不在集合中,向左走 4→3→2→1→0t 停在 0,长度 4 - 0 = 4
  • 100200 各自成段,长度均为 1

每条连续序列只在处理其最大值时统计一次,每个数最多被向左访问一次,总时间复杂度 O(n)O(n),空间复杂度 O(n)O(n)

代码#

class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
nums = set(nums)
ans = 0
for x in nums:
if x + 1 in nums: continue
t = x
while t in nums: t -= 1
ans = max(ans, x - t)
return ans
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

最长连续序列
https://www.hygen.red/posts/hot100/01-哈希/003最长连续序列/
作者
Hygen
发布于
2026-06-16
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录