chenjunda
长期主义

最长连续序列

2025-06-29 leecode Hot100

128. 最长连续序列

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

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

示例 1:

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

示例 2:

1
2
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

示例 3:

1
2
输入:nums = [1,0,1,2]
输出:3

提示:

  • 0 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9

拿到这道题的一开始还准备直接开辟10001的数组仿制哈希set来解决,没想到忘记了负数的存在,并且这道题是10^9开不了那么大的数

本题的核心是发掘hashSet的本质特点,hashSet的特点是什么呢?那么这道题是如何借助hashSet的特点来解决的呢?

只知道解法还是不够,得知道解决问题的本质,于是我问了chatGpt

chatGPT:

这个问题问得非常深入,非常 INFJ 式地想挖“本质与灵感来源”,我来尽量用你喜欢的方式解释:


✅ 一、HashSet 被用到的两个关键“性质”

🌟 1. 快速查找 O(1) —— set.contains(x)

判断一个数是否存在,不用遍历,直接查,时间复杂度 O(1)

这是最关键的特性。因为我们需要在序列中判断一个数的“前一个”或“后一个”是否存在,HashSet 能极快完成这个判断。


🌟 2. 去重

数组里可能有重复项,HashSet 自动帮你去重

这对于 nums = [1,0,1,2] 这种输入是必要的,否则你可能会重复处理。


✅ 二、这道题的“感觉”或“直觉”

很多人第一反应会是:排序 → 然后遍历。但排序是 O(nlogn),不符合要求。

而这道题的 直觉点在于

🌱“只要我知道一个连续序列的起点,我就可以一路 +1 找下去。”


💡 于是我们思考:

如果我能快速知道一个数是否在原数组中,那我就能从每个可能的起点 x 出发,查 x+1, x+2...,直到查不到为止。

但怎么快速查?
👉 这就自然想到 HashSet!


✅ 所以,问题就转化成了:

  • 先把所有数字放到 set 中
  • 从每个“可能的起点”出发往右找

🚩 如何判断某个数是“起点”?

答案是:

1
2
3
4
5
java


复制编辑
if (!set.contains(num - 1))

也就是:

只有当 num-1 不存在时,num 才是这个连续序列的第一个数。

这样就保证了每个序列只被处理一次,时间复杂度 O(n)。


✅ 总结:为什么 HashSet 是灵魂

特性 在这道题中的作用
查找快 O(1) 快速判断某个数是否存在
去重 防止重复处理同一个数字
空间换时间 用 O(n) 空间换 O(n) 时间
语义契合 “是否存在”的判断语义就是 Set 本质

🌌 最后的“感觉”总结一句话:

这道题的关键感受是:“我需要快速判断一个数字是否存在”,这种需求一出现,HashSet 就成了最自然的选择,它的 contains() 就像“意识的触角”一样可以立刻知晓答案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static int longestConsecutive(int[] nums) {
HashSet<Integer> set = new HashSet<>();
int ans=0;
for (int i = 0; i < nums.length; i++) {
if(!set.contains(nums[i])) {
set.add(nums[i]);
}
}
for (Integer i : set) {
if(!set.contains(i-1)) {
int cur=i;
int len=1;
while(set.contains(cur+1)) {
len++;
cur++;
}
ans = Math.max(ans, len);
}
}
return ans;
}

Author: chenjunda

Link: http://example.com/2025/06/29/%E6%9C%80%E9%95%BF%E8%BF%9E%E7%BB%AD%E5%BA%8F%E5%88%97/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
苍穹外卖day01
NextPost >
反射&动态代理
CATALOG
  1. 1. ✅ 一、HashSet 被用到的两个关键“性质”
    1. 1.1. 🌟 1. 快速查找 O(1) —— set.contains(x)
    2. 1.2. 🌟 2. 去重
  2. 2. ✅ 二、这道题的“感觉”或“直觉”
    1. 2.1. 💡 于是我们思考:
    2. 2.2. ✅ 所以,问题就转化成了:
    3. 2.3. 🚩 如何判断某个数是“起点”?
  3. 3. ✅ 总结:为什么 HashSet 是灵魂
  4. 4. 🌌 最后的“感觉”总结一句话: