128. 最长连续序列
Posted 炫云云
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了128. 最长连续序列相关的知识,希望对你有一定的参考价值。
128. 最长连续序列
给定一个未排序的整数数组 nums
,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n)
的算法解决此问题。
示例 1:
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
哈希表
我们考虑枚举数组中的每个数 x x x, 考虑以其为起点, 不断尝试匹配 x + 1 , x + 2 , ⋯ x+1, x+2, \\cdots x+1,x+2,⋯ 是否存在,假设 最长匹配到了 x + y x+y x+y, 那么以 x x x 为起点的最长连续序列即为 x , x + 1 , x + 2 , ⋯ , x + y x, x+1, x+2, \\cdots, x+y x,x+1,x+2,⋯,x+y, 其长度为 y + 1 y+1 y+1, 我们不断枚举并更新答案即可。
对于匹配的过程用一 个哈希表存储数组中的数, 这样查看一个数是否存在即能优化至 O ( 1 ) O(1) O(1) 的时间复杂度。
仅仅是这样我们的算法时间复杂度最坏情况下还是会达到 O ( n 2 ) O\\left(n^{2}\\right) O(n2) (即外层需要枚举 O ( n ) O(n) O(n) 个数, 内层 需要暴力匹配 O ( n ) O(n) O(n) 次),无法满足题目的要求。但仔细分析这个过程,我们会发现其中执行了很 多不必要的枚举, 如果已知有一个 x , x + 1 , x + 2 , ⋯ , x + y x, x+1, x+2, \\cdots, x+y x,x+1,x+2,⋯,x+y 的连续序列,而我们却重新从 x + 1 x+1 x+1, x + 2 x+2 x+2 或者是 x + y x+y x+y 处开始尝试匹配,那么得到的结果肯定不会优于枚举 x x x 为起点的答案,因此我们 在外层循环的时候碰到这种情况跳过即可。
那么怎么判断是否跳过呢?由于我们要枚举的数 x x x 一定是在数组中不存在前驱数 x − 1 x-1 x−1 的,不然按 照上面的分析我们会从 x − 1 x-1 x−1 开始尝试匹配,因此我们每次在哈希表中检查是否存在 x − 1 x-1 x−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: # 不存在前驱数 x-1
current_num = num # 当前匹配数字
current_streak = 1 # 当前匹配长度
while current_num +1 in num_set: # 查看x+1是否在哈希表中
current_num +=1 # 当前匹配数字 x+1
current_streak +=1 # 当前匹配长度 +1
longest_streak = max(longest_streak, current_streak)
return longest_streak
- 用哈希表存储每个端点值对应连续区间的长度
- 若数已在哈希表中:跳过不做处理
- 若是新数加入:
- 取出其左右相邻数已有的连续区间长度 left 和 right
- 计算当前数的区间长度为:
cur_length = left + right + 1
- 根据 cur_length 更新最大长度 max_length 的值
- 更新区间两端点的长度值
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 max_length
参考
以上是关于128. 最长连续序列的主要内容,如果未能解决你的问题,请参考以下文章