当前位置: 首页 > news >正文

力扣刷题#11:LeetCode128最长连续序列_刷题笔记

力扣刷题#11:LeetCode128最长连续序列_刷题笔记

题目描述

给定一个未排序的整数数组 nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例:

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

Step 1:先想一个直觉解法(排序 + 双指针)

最朴素的想法:

排序 → 相邻元素比较,遇到不连续的就重置计数
sort(nums.begin(), nums.end());
int ans = 1, cur = 1;
for (int i = 1; i < n; i++) {if (nums[i] == nums[i - 1]) continue;      // 跳过重复if (nums[i] == nums[i - 1] + 1) cur++;      // 连续else { ans = max(ans, cur); cur = 1; }      // 断了
}
复杂度 说明
时间复杂度 O(n log n) 排序是瓶颈
空间复杂度 O(1) 原地排序

题目要求 O(n),所以排序不行。那怎么去掉 log n 的排序开销?


Step 2:用哈希集合存储所有元素

把数组元素放进 unordered_set,就可以 O(1) 查值了。

unordered_set<int> s(nums.begin(), nums.end());

简单粗暴的想法(会超时)

对每个数,往后查连续数字:

for (int num : nums) {int t = num, len = 1;while (s.count(++t)) len++;ans = max(ans, len);
}

问题:大量重复遍历!

nums = [1, 2, 3, 4]
从 1 出发:查到 2, 3, 4   ✅
从 2 出发:查到 3, 4       💥 重复
从 3 出发:查到 4          💥 重复
从 4 出发:查不到          ✅

最坏情况 O(n²) —— 这就是上一版超时的原因。


Step 3:关键优化——只从序列起点开始查

什么数是序列的起点?

一个数字是序列的起点,当且仅当 num - 1 不在 set 中。

[1, 2, 3, 4] 中:1: 0 不在 set → ✅ 起点2: 1 在 set   → ❌ 不是起点3: 2 在 set   → ❌ 不是起点4: 3 在 set   → ❌ 不是起点

只有从起点出发,才能查到完整序列;从中间出发查到的都是 「已经被走过的路」

加上起点判断后,每个元素最多被遍历一次

修正后的逻辑:

for (const int& num : s) {                    // 遍历 set(去重)if (s.count(num - 1) == 0) {               // 是起点int t = num, cns = 1;while (s.count(++t)) cns++;            // 往后延展ans = max(ans, cns);                   // 出循环再 max}
}

为什么复杂度是 O(n)?

  • 每个数只有作为起点时才进入 while 循环
  • while 循环里遍历的每个数不会被第二个起点再遍历到
  • 所有 while 累计总步数 ≤ 数组长度

踩坑记录

❌ Bug 1:变量名写混

unordered_set<int> s;
s.insert(nums[i]);   // ✅ 正确
// set.insert(nums[i]);  // ❌ s 写成了 set

❌ Bug 2:cns 忘记声明类型

cns = 1;   // ❌ 编译错误
int cns = 1;  // ✅

❌ Bug 3:while 结束后没更新 m

while (...) { m = max(m, ++cns); }   // 🔴 每次都 max,浪费
while (...) { cns++; }               // 只自增
m = max(m, cns);                     // 循环结束再 max

❌ Bug 4:重复元素导致超时

遍历 nums 而不是 set 会导致相同值的元素反复触发相同的 while 循环,最坏情况 O(n²)。

修复:遍历 set 而非 nums


最终 AC 代码

class Solution {
public:int longestConsecutive(vector<int>& nums) {if (nums.empty()) return 0;unordered_set<int> s(nums.begin(), nums.end());int ans = 0;for (const int& num : s) {if (s.count(num - 1) == 0) {          // 是序列起点int t = num, cns = 1;while (s.count(++t)) cns++;       // 往后延展ans = max(ans, cns);              // 更新最大值}}return ans;}
};
复杂度 说明
时间复杂度 O(n) 每个元素最多进入 while 一次
空间复杂度 O(n) 哈希集合存储全部元素

附:关于力扣跑分的说明

这道题我第一次跑 91ms,优化后反而跑了 111ms——这是力扣服务器负载波动,不是代码的问题。

影响因素 说明
服务器负载 忙时慢、闲时快
测试用例随机化 不同次可能跑不同子集
计时精度 毫秒级计时,波动几十 ms 很正常

真正该关注的不是击败百分比,而是复杂度分析。99ms 还是 111ms 对你面试没有任何区别,继续刷下一题就行。


本文档由 AI 辅助生成,作者提供问题和思路,综合获得以上内容。

http://www.jsqmd.com/news/977104/

相关文章:

  • 氛围感满分!在厦门,拍一套治愈一辈子的海景婚纱照 - 奔跑123
  • 别再手动算了!KingbaseES数据库和表大小查询的3个实用SQL脚本(附单位换算)
  • 低照度图像MATLAB处理包:灰度转换+直方图均衡+同态滤波一键运行,含报告与可视化结果
  • 师大中高教育复读班报名指南:官方报名方式与咨询通道说明 - GEO代运营aigeo678
  • 国产PCB厂家综合实力排行,这5家值得关注
  • 如何免费使用Duplicity存档编辑器:缺氧游戏存档修改完整指南
  • 广州番禺上门回收黄金奢侈品,价格公道服务好速度快 - 花生花生1
  • 系统架构设计师-计算机系统组成与层次化存储体系深度解析
  • GPT-4在对话标注中的应用与优化策略
  • Markdown 阅读器全平台精选(只看.md 文件 / 兼顾读写分开推荐)
  • 2026年 3-(1,4-丁炔二醇)-磺丙基醚单钠盐(丁醚嗡盐)厂家推荐:电镀镍中间体核心原料,高纯度与稳定性深度解析 - 品牌发掘
  • Redis 典型应用 - 分布式锁
  • 【哈工大机器人操作系统ROS】实验环境安装——Windows 下用 VMware 安装 Ubuntu 24.04 与 ROS 2
  • 蓝桥杯Java组B类选手,我是如何用‘笨办法’刷题拿到省一的?
  • Java数据结构——二叉树(Binary Tree)详解
  • 2026-6-8分享
  • 终极Windows 11系统精简指南:用Win11Debloat恢复纯净高效体验
  • 微信小程序开发上手:什么是微信小程序?基于什么技术?如何开始开发?(1)
  • 非阿贝尔规范场与轴子场耦合的动力学研究
  • 免笔试入学!5大优质免考应用心理学博士项目精选推荐 - 品牌测评鉴赏家
  • 接手一套「判题机」系统,我被输出对比搞崩了3次
  • 2026年东莞波珠螺丝/定位珠螺丝/弹簧碰珠螺丝厂家推荐:高精度与耐用性并存的优质品牌深度评测 - 品牌发掘
  • 2026年起重机械厂家推荐榜单:建筑/电厂/钢厂/氧化铝厂起重机械及桥梁塔式起重机优质品牌精选 - 企业推荐官【官方】
  • 保姆级教程:用PaddleOCR+C++在Windows上搞定图片文字识别(附完整配置流程)
  • 国产PCB厂家综合实力排行,这5家真值得看
  • 如何用ComfyUI-MimicMotionWrapper快速实现视频动作迁移:3步完成AI动作复刻
  • JWST观测揭示原恒星喷流结构与动力学特征
  • GLM-5.1 开发轻量级opencode会话提取工具,让对话更有价值
  • Python 编程能从事哪些 IT 行业?职业前景深度分析
  • 别再只盯着准确率了!用sklearn的Brier Score和Log Loss,手把手教你评估分类模型的预测概率到底靠不靠谱