【Hot100|3 LeetCode 128. 最长连续序列】
这段代码是解决「LeetCode 128. 最长连续序列」问题的经典高效解法,核心思路是利用哈希集合(HashSet)的快速查找特性,通过 “判断序列起点 + 向后延伸” 的方式,在 O(n) 时间复杂度内找到最长的连续元素序列。下面从「问题理解→核心思路→代码逐行解析→实例演示」四个维度详细讲解:
一、问题理解
「最长连续序列」问题要求:给定一个未排序的整数数组 nums,找出其中最长的连续元素序列的长度(连续指的是数值连续,如 1,2,3,4 是长度为 4 的连续序列,100,200 是长度为 1 的两个独立序列)。限制:算法的时间复杂度需尽可能低(最好能达到 O(n))。
二、核心思路
暴力解法(排序后遍历)的时间复杂度是 O(n log n)(受排序影响),而该解法通过哈希集合优化查找效率,核心思路是:
- 去重 + 快速查找:用 HashSet 存储所有元素,既去重(重复元素不影响连续序列长度),又支持
O(1)时间判断元素是否存在。 - 只从序列起点计算长度:对于每个元素
x,只有当x-1不存在于集合中时,x才是某个连续序列的起点(避免对同一序列的中间元素重复计算)。 - 向后延伸计算长度:从起点
x开始,依次检查x+1, x+2, ...是否存在,直到找不到为止,这段连续序列的长度为y - x(y是第一个不存在的元素)。
三、代码逐行解析
java
运行
class Solution {public int longestConsecutive(int[] nums) {// 1. 创建HashSet存储所有元素(去重+O(1)查找)Set<Integer> st = new HashSet<>();for (int num : nums) {st.add(num);}// 2. 记录最长连续序列的长度(初始为0,空数组时直接返回0)int ans = 0;// 3. 遍历集合中的每个元素for (int x : st) {// 3.1 判断x是否是连续序列的起点:若x-1存在,说明x不是起点,跳过if (st.contains(x - 1)) {continue;}// 3.2 若x是起点,向后延伸找最长连续序列int y = x + 1; // 从x的下一个元素开始检查while (st.contains(y)) { // 只要y存在,就继续向后找y++;}// 3.3 计算当前连续序列的长度(y - x),更新最长长度ans = Math.max(ans, y - x);}// 4. 返回最长连续序列的长度return ans;}
}
关键细节拆解:
HashSet 的作用
Set<Integer> st = new HashSet<>()及循环st.add(num):- 去重:数组中重复的元素(如
[1,1,2])在集合中只会保留一个,避免重复处理。 - 快速查找:
st.contains()方法的时间复杂度是O(1),为后续 “判断起点” 和 “向后延伸” 提供高效支持。
- 去重:数组中重复的元素(如
判断序列起点的核心逻辑
if (st.contains(x - 1)) { continue; }:- 若
x-1存在于集合中,说明x不是某个连续序列的起点(因为x-1才是更前面的元素),此时跳过x可避免重复计算(例如序列1,2,3,4中,x=2时x-1=1存在,跳过;只从x=1开始计算)。 - 若
x-1不存在,说明x是起点,此时需要计算从x开始的连续序列长度。
- 若
向后延伸计算长度
int y = x + 1:从起点x的下一个元素开始检查。while (st.contains(y)) { y++; }:只要y存在于集合中,就继续向后移动y(例如x=1时,y会依次变为2,3,4,直到y=5不存在为止)。y - x:此时y是第一个不在序列中的元素,因此x到y-1的连续序列长度为y - x(如x=1, y=5时,长度为5-1=4)。
更新最长长度
ans = Math.max(ans, y - x):用当前序列的长度更新全局最长长度,最终ans就是结果。
四、实例演示
以测试用例 nums = [100, 4, 200, 1, 3, 2] 为例,演示执行过程:
去重后集合:
st = {100, 4, 200, 1, 3, 2}。初始化:
ans = 0。遍历集合元素:
x=100:检查x-1=99是否存在?否(是起点)。y=101,st中无 101,长度101-100=1→ans=1。x=4:检查x-1=3是否存在?是(3 在集合中)→ 跳过。x=200:检查x-1=199是否存在?否(是起点)。y=201,无 → 长度1→ans仍为 1。x=1:检查x-1=0是否存在?否(是起点)。y=2(存在)→y=3(存在)→y=4(存在)→y=5(不存在)。长度5-1=4→ans=4。x=3:检查x-1=2是否存在?是 → 跳过。x=2:检查x-1=1是否存在?是 → 跳过。
最终结果:
ans=4(对应序列1,2,3,4)。
五、复杂度分析
- 时间复杂度:
O(n)每个元素最多被访问两次:一次是在遍历集合时作为x被检查,一次是在while循环中作为y被延伸(例如1,2,3,4中,1被检查一次,2,3,4被while循环访问一次)。整体遍历次数为O(n)。 - 空间复杂度:
O(n)哈希集合需要存储所有元素,最坏情况下(无重复元素)空间为O(n)。
总结
该解法的核心是通过 “只处理序列起点” 避免重复计算,结合哈希集合的 O(1) 查找特性,将时间复杂度优化到线性级别,是解决该问题的最优方案之一。这种 “利用哈希表优化查找 + 精准定位计算起点” 的思路,也是面试中高频考察的算法设计思想。
