【leetCode】128. 最长连续序列(hard)
原创
©著作权归作者所有:来自51CTO博客作者wx62d4c4d0ec83a的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、题目描述
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 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
复杂度分析
- 时间复杂度:O(n),其中 n 为数组的长度。具体分析已在上面正文中给出。
- 空间复杂度:O(n)。哈希表存储数组中所有的数需要 O(n) 的空间。
参考:
LeetCode官方题解
2.2 动态规划
解题思路:
题目要求 O(n) 复杂度。
- 用哈希表存储每个端点值对应连续区间的长度
- 若数已在哈希表中:跳过不做处理
- 若是新数加入:
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题解