力扣(LeetCode)100题:128.最长连续序列

128.最长连续序列128.最长连续序列
我的题解:通过排序+计数的方式进行完成。开始我用的是自己写的冒泡排序来进行排序但是后续运行发现时间复杂度过高运行超时就用系统自带的了(后续会去学一手时间复杂度低的排序)
128.最长连续序列

class Solution:
    def longestConsecutive(self, nums: List[int]) -> int:
        
        if not nums:
            return 0
        
        dic_num = collections.defaultdict(list)
        col=[0]*len(nums)
        nums_s=sorted(nums)
        for i,num in enumerate(nums_s):

            if num not in dic_num:
                dic_num[num].append(i)
                col[i]+=1
                if num-1 in dic_num:
                    col[i]=col[i-1]+1
            else:
                col[i]=col[i-1]
        ma=max(col)
        return ma

官方题解:

方法一:哈希表

这段代码实现了 O(n) 时间复杂度 的“最长连续序列”算法,核心思想是:只从每个连续序列的起点开始计数,避免重复遍历。下面逐行解析逻辑(不包括类和函数定义):


1. 初始化结果变量

longest_streak = 0
  • 用于记录全局最长的连续序列长度。

2. 将输入转为集合(哈希表)

num_set = set(nums)
  • 去重:消除重复数字对连续性判断的干扰;
  • O(1) 查找:后续可通过 in 操作快速判断某个数字是否存在。

3. 遍历集合中的每个数字

for num in num_set:
  • 注意:遍历的是去重后的数字,避免无效重复计算。

4. 判断是否为连续序列的“起点”

if num - 1 not in num_set:
  • 关键优化:只有当 num - 1 不存在时,num 才是一个连续序列的起始点
  • 举例:
    • 若集合中有 [100, 4, 200, 1, 3, 2]
    • num = 1 时,0 不在集合中 → 是起点;
    • num = 2 时,1 在集合中 → 不是起点,跳过。
  • 这样确保每个连续序列只被完整遍历一次,总时间复杂度为 O(n)。

5. 从起点开始向后扩展

current_num = num
current_streak = 1
  • current_num:当前检查的数字;
  • current_streak:当前连续序列的长度(至少为 1,包含起点自身)。

6. 向右延伸连续序列

while current_num + 1 in num_set:
    current_num += 1
    current_streak += 1
  • 不断检查下一个整数(current_num + 1)是否存在于集合中;
  • 如果存在,序列长度加 1,并继续向后探测;
  • 直到找不到下一个连续数字为止。

例如:起点 num = 1,集合中有 2, 3, 4,则循环会依次找到 2→3→4,最终 current_streak = 4


7. 更新全局最长长度

longest_streak = max(longest_streak, current_streak)
  • 每次完成一个连续序列的探测后,更新全局最大值。

✅ 算法优势总结

特点说明
时间复杂度 O(n)每个数字最多被访问两次(一次在外层循环,一次在 while 中),均摊 O(1)
空间复杂度 O(n)需要额外集合存储去重后的数字
无需排序完全基于哈希查找,避免 O(n log n) 排序开销
自动去重集合天然消除重复元素干扰

🧪 示例演示

输入:nums = [100, 4, 200, 1, 3, 2]
num_set = {1, 2, 3, 4, 100, 200}

  • num = 10099 不在 → 序列 [100] → 长度 1
  • num = 43 在 → 跳过
  • num = 200199 不在 → 序列 [200] → 长度 1
  • num = 10 不在 → 序列 [1,2,3,4] → 长度 4
  • num = 32 在 → 跳过
  • num = 21 在 → 跳过

最终结果:4


💡 关键洞察

“只从起点开始计数” 是本解法的核心。
它避免了对 [1,2,3,4] 中的 2,3,4 分别做无用遍历,从而将暴力 O(n²) 优化到 O(n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值