news 2026/4/23 12:39:57

【Hot100-Java中等】/LeetCode 128. 最长连续序列:如何打破排序思维,实现 O(N) 复杂度?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Hot100-Java中等】/LeetCode 128. 最长连续序列:如何打破排序思维,实现 O(N) 复杂度?

在 LeetCode 的算法题中,“最长连续序列” (Longest Consecutive Sequence)是一道非常经典的Hot 100题目。它考察的不是复杂的算法模板,而是对哈希表特性的灵活运用以及对时间复杂度的精确控制。

1. 题目核心难点

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

关键限制请你设计并实现时间复杂度为的算法解决此问题。

为什么不能排序?

看到“连续序列”,直觉反应通常是先排序,然后遍历一遍统计。

  • 排序算法(如快速排序、归并排序)的时间复杂度下限是

  • 题目严格要求,这意味着排序是被禁止的。我们必须在不排序的情况下,通过“查找”来还原序列。


2. 核心思路:哈希表 + “跳过逻辑”

要在时间内知道“某个数字是否存在”,只能依靠哈希表 (HashSet)

步骤一:去重与快速查找

首先,将数组中所有元素放入HashSet中。

  • 目的 1:实现的查找复杂度。

  • 目的 2:去重(虽然这一步不是必须的,但遍历 Set 比遍历原数组更稳健,详见后文分析)。

步骤二:寻找序列的“起点” (关键优化)

这是算法能达到的核心原因。

假设数组是 [100, 4, 200, 1, 3, 2]。哈希表中包含了这些数字。

当我们遍历到数字 3 时,我们要不要开始数数(寻找 4, 5...)?

  • 不要。因为3的前面有2。既然2存在,3肯定不是一个连续序列的开头。我们应该等待遍历到2(甚至1)时再处理。

  • 规则只有当num - 1不在哈希表中时,num才是序列的起点,我们才开始向后计数。


3. 代码实现与详解

Java

class Solution { public int longestConsecutive(int[] nums) { // 1. 使用 HashSet 存储所有数字,实现 O(1) 查询并去重 Set<Integer> num_set = new HashSet<Integer>(); for (int num : nums) { num_set.add(num); } int longestStreak = 0; // 2. 遍历哈希表中的每个数字 for (int num : num_set) { // 3. 【关键判断】只有当 num 是序列的起点时(即 num-1 不存在),才开始匹配 if (!num_set.contains(num - 1)) { int currentNum = num; int currentStreak = 1; // 4. 不断查询 num+1, num+2... 是否存在 while (num_set.contains(currentNum + 1)) { currentNum += 1; currentStreak += 1; } // 5. 更新最大长度 longestStreak = Math.max(longestStreak, currentStreak); } } return longestStreak; } }

4. 深度解析:为什么这是 O(N)?

很多初学者看到for循环里套了一个while循环,第一反应就是:“这不是吗?”

其实不然。我们要从每个元素被访问的次数来分析:

  1. 外层循环:每个元素最多被访问 1 次。

  2. 内层while循环

    • 只有当一个数是“起点”时,才会进入while

    • 举例[1, 2, 3, 4]

      • 访问44-1存在,跳过。

      • 访问33-1存在,跳过。

      • 访问22-1存在,跳过。

      • 访问11-1不存在,是起点。进入while,依次访问2, 3, 4

    • 结论:数组中的每个数字,只会被while循环内部访问最多一次(就是在统计属于它的那个序列长度时)。

总操作次数(存入Set) +(外层遍历) +(内层while累计总次数)。

,忽略常数后为


5. 易错点分析:遍历nums还是遍历Set

在实现时,有人会习惯写成for (int num : nums)来遍历原数组。虽然在大多数情况下也能通过,但存在隐患

潜在风险:重复元素的陷阱

如果输入数组包含大量重复的“起点”,例如:

nums = [1, 1, 1, ..., 1, 2, 3, 4, ... 1000]

  • 遍历nums:程序会遇到第一个1,发现0不在,扫描一遍11000。接着遇到第二个1,又扫描一遍11000……这将导致算法退化为并超时。

  • 遍历Set(官方解法):Set天然去重。无论原数组有多少个1Set中只有一个1,内层循环只会执行一次。

因此,始终推荐遍历Set而不是原数组,这是保证算法稳定的最佳实践。

总结

解决 LeetCode 128 题的关键在于转换思维:

  1. 空间换时间:用哈希表代替排序,消除的瓶颈。

  2. 剪枝优化:通过!set.contains(x-1)这一判断,精准定位序列起点,避免了对同一个序列中间元素的重复无效计算,将复杂度严格控制在

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 12:12:24

PyTorch-CUDA-v2.9镜像自动混合精度训练配置指南

PyTorch-CUDA-v2.9镜像自动混合精度训练配置指南 在深度学习的实战中&#xff0c;一个常见的场景是&#xff1a;你刚刚拿到一台新的GPU服务器&#xff0c;满心期待地准备跑起模型&#xff0c;结果却卡在了环境配置上——CUDA版本不匹配、cuDNN缺失、PyTorch编译失败……这样的经…

作者头像 李华
网站建设 2026/4/23 5:11:08

PyTorch-CUDA-v2.9镜像如何保护模型版权?水印技术探讨

PyTorch-CUDA-v2.9镜像如何保护模型版权&#xff1f;水印技术探讨 在AI模型日益成为核心资产的今天&#xff0c;一个训练好的深度神经网络可能承载着数月的研发投入和大量私有数据。然而&#xff0c;一旦模型以 .pt 或 ONNX 格式发布&#xff0c;它就极易被复制、微调后重新打…

作者头像 李华
网站建设 2026/4/22 14:04:48

Adobe Illustrator脚本集合:设计师效率革命性解决方案

Adobe Illustrator脚本集合&#xff1a;设计师效率革命性解决方案 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 你是否曾经在Adobe Illustrator中花费数小时重复相同的操作&#…

作者头像 李华
网站建设 2026/4/16 19:58:14

WindowResizer:突破窗口限制,轻松掌控屏幕布局的实用神器

WindowResizer&#xff1a;突破窗口限制&#xff0c;轻松掌控屏幕布局的实用神器 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 在日常电脑使用中&#xff0c;你是否遇到过无法调…

作者头像 李华