跳到主要内容

0128. 最长连续序列

题目描述

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

示例 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,1,2,3,4,5,6,7,8]。它的长度为 9。

解题思路

第一步:理解问题

要找的是值连续的序列,不是数组中位置连续的子数组。

比如 [100, 4, 200, 1, 3, 2],数值连续的序列有 [100][200][1, 2, 3, 4]

第二步:暴力解法

先排序,然后遍历找最长连续段:

def longestConsecutive(nums):
if not nums:
return 0
nums = sorted(set(nums))
ans = 1
cur = 1
for i in range(1, len(nums)):
if nums[i] == nums[i-1] + 1:
cur += 1
ans = max(ans, cur)
else:
cur = 1
return ans
  • 时间复杂度:O(n log n)(排序)
  • 空间复杂度:O(n)(去重)

第三步:优化解法

题目要求 O(n) 时间复杂度,不能用排序。那只能通过哈希集合的 O(1) 查找来加速。

朴素想法:对每个数字,向右逐个查找 num+1, num+2, ... 是否在集合中。

def longestConsecutive(nums):
st = set(nums)
ans = 0
for x in st:
y = x + 1
while y in st:
y += 1
ans = max(ans, y - x)
return ans

但这可能会退化到 O(n²),因为如果一个数字是很多连续序列的内部元素,它会被重复计算。

第四步:最优解法 - 只从序列起点开始

优化:只从序列的起点(即 x-1 不在集合中的数字 x)开始向右扩展。

这样每个数字最多被访问两次:一次作为其他序列的内部元素被跳过,一次作为起点被遍历。

时间复杂度严格为 O(n)


完整代码实现

from typing import List

class Solution:
"""
128. 最长连续序列 - 哈希表

核心思想:
利用哈希集合 O(1) 查找的特性,只从序列起点开始向右扩展连续序列。

时间复杂度:O(n)
空间复杂度:O(n),哈希集合
"""

def longestConsecutive(self, nums: List[int]) -> int:
st = set(nums)
ans = 0

for x in st:
if x - 1 in st:
continue

y = x + 1
while y in st:
y += 1

ans = max(ans, y - x)

return ans

示例推演

nums = [100, 4, 200, 1, 3, 2] 为例。

集合 st = {1, 2, 3, 4, 100, 200}

x = 10 不在集合中,是起点。

  • y = 2 在, y = 3 在, y = 4 在, y = 5 不在
  • 序列长度 = 5 - 1 = 4,ans = 4

x = 21 在集合中,跳过(不是起点)

x = 32 在集合中,跳过

x = 43 在集合中,跳过

x = 10099 不在,是起点。

  • y = 101 不在
  • 序列长度 = 1,ans = 4

x = 200199 不在,是起点。

  • y = 201 不在
  • 序列长度 = 1,ans = 4

最终答案:4


复杂度分析

解法时间复杂度空间复杂度说明
暴力排序O(n log n)O(n)先排序再扫描
朴素哈希O(n²)O(n)每个数字都作为起点
优化哈希O(n)O(n)最优解

易错点总结

1. 为什么要跳过 x-1 在集合中的数字?

这是最关键的一步。如果不跳过,内部元素会被重复遍历,退化为 O(n²)

2. 序列长度的计算

y 最终停在第一个不在集合中的数,所以序列长度是 y - x,不是 y - x + 1

3. 空数组

nums 为空时,集合为空,循环不执行,返回 0


扩展思考

并查集做法

也可以把所有相邻的数字用并查集合并,最后统计每个连通块的大小。时间复杂度也是 O(n),但常数较大,不推荐。

如果要求返回具体的序列?

只需要在遍历时记录起点和终点即可。

相关题目

加载评论中...