一、题目描述

给定一个未排序的整数数组,找出最长连续序列的长度。

要求算法的时间复杂度为 O(n)。

示例:

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

二、解题思路 & 代码

2.1 哈希表

class Solution:
def longestConsecutive(self, nums):
longest_streak = 0
num_set = set(nums)

for num in num_set:
if num - 1 not in num_set:
current_num = num
current_streak = 1

while current_num + 1 in num_set:
current_num += 1
current_streak += 1

longest_streak = max(longest_streak, current_streak)

return

复杂度分析

  1. 时间复杂度:O(n),其中 n 为数组的长度。具体分析已在上面正文中给出。
  2. 空间复杂度:O(n)。哈希表存储数组中所有的数需要 O(n) 的空间。

参考:
​​​LeetCode官方题解​

2.2 动态规划

解题思路:
题目要求 O(n) 复杂度。

  1. 用哈希表存储每个端点值对应连续区间的长度
  2. 若数已在哈希表中:跳过不做处理
  3. 若是新数加入:
    1)取出其左右相邻数已有的连续区间长度​​​left​​​ 和​​right​​​ 2)计算当前数的区间长度为:​​cur_length = left + right + 1​​ 3)根据 ​​cur_length​​ 更新最大长度 ​​max_length​​ 的值
    4)更新区间两端点的长度值
class Solution(object):
def longestConsecutive(self, nums):
hash_dict = dict()

max_length = 0
for num in nums:
if num not in hash_dict:
left = hash_dict.get(num - 1, 0)
right = hash_dict.get(num + 1, 0)

cur_length = 1 + left + right
if cur_length > max_length:
max_length = cur_length

hash_dict[num] = cur_length
hash_dict[num - left] = cur_length
hash_dict[num + right] = cur_length

return

参考:
​​​LeetCode题解​

2.3 并查集

class DSU:
def __init__(self, nums):
self.pre = {num: num for num in nums}
self.rank = collections.defaultdict(lambda: 1)
self.cnt = collections.defaultdict(lambda: 1)
def find(self, x):
while x != self.pre[x]:
x = self.pre[x]
return x
def merge(self, x, y):
if y not in self.pre:
return 1
root1, root2 = self.find(x), self.find(y)
if root1 == root2:
return self.cnt[root1]
if self.rank[root1] < self.rank[root2]:
self.pre[root1] = root2
self.cnt[root2] += self.cnt[root1]
return self.cnt[root2]
elif self.rank[root1] > self.rank[root2]:
self.pre[root2] = root1
self.cnt[root1] += self.cnt[root2]
return self.cnt[root1]
else:
self.pre[root1] = root2
self.cnt[root2] += self.cnt[root1]
self.rank[root2] += 1
return self.cnt[root2]
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
dsu = DSU(nums)
res = 0
for num in nums:
res = max(res, dsu.merge(num, num + 1))
return

参考:
​​​leetCode题解​