Title

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

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

示例:

输入: [100, 4, 200, 1, 3, 2]

输出: 4

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

Solve

暴力

没想到啊,暴力的方法竟然能AC,直接排序,然后遍历整个序列,判断当前项与前一项的差,为0则continue,为1则+1,其它情况更新ans。

class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
if not nums:
return 0

nums.sort()
ans, temp = 0, 0
for index in range(1, len(nums)):
if nums[index] - nums[index - 1] == 1:
temp += 1
elif nums[index] - nums[index - 1] == 0:
continue
else:
ans = max(ans, temp)
temp = 0
ans = max(ans, temp)
return ans + 1

哈希表:

考虑枚举数组中的每个数 x,考虑以其为起点,不断尝试匹配 x+1, x+2, ⋯ 是否存在,假设最长匹配到了 x+y,那么以 x 为起点的最长连续序列即为 x, x+1, x+2, ⋯,x+y,其长度为 y+1。

但仔细分析这个过程,我们会发现其中执行了很多不必要的枚举,如果已知有一个 x, x+1, x+2,⋯,x+y 的连续序列,而我们却重新从 x+1,x+2 或者是 x+y 处开始尝试匹配,那么得到的结果肯定不会优于枚举 x 为起点的答案,因此我们在外层循环的时候碰到这种情况跳过即可。

那么怎么判断是否跳过呢?由于我们要枚举的数 x 一定是在数组中不存在前驱数 x-1 的,不然按照上面的分析我们会从 x-1 开始尝试匹配,因此我们每次在哈希表中检查是否存在 x-1 即能判断是否需要跳过了。

复杂度分析

时间复杂度:O(n),其中 n 为数组的长度。具体分析已在上面正文中给出。

空间复杂度:O(n)。哈希表存储数组中所有的数需要 O(n) 的空间。

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 longest_streak