文章目录
一、题目描述
给定一个 未排序的整数数组 nums ,要求找出其中的 最长连续元素序列的长度。
✅ 连续序列 指的是数字可以按顺序排列,不要求原数组中相邻。
- 例如:
输入:nums = [100, 4, 200, 1, 3, 2]
输出:4
解释:最长连续序列是[1, 2, 3, 4]。
二、题目目标与挑战
- 不能排序后简单遍历 ------ 排序是
O(n log n),而本题要求能在平均O(n)时间解决。 - 要快速判断某个数字是否存在 ------ 用哈希结构(Set)是关键。
三、思路分析
解法一:HashSet + 边界扩展法(最优解)
核心思想:
- 利用
HashSet存储所有元素,保证查找存在性是O(1)。 - 只从可能是连续序列"起点"的数字向右扩展,
即:如果num - 1不在集合中,那么num就是一个连续序列的开头。 - 扩展
num + 1、num + 2...直到不连续为止。
算法流程图
num-1 不在集合中
num-1 在集合中
输入数组 nums
将所有元素插入 HashSet
初始化 maxLen = 0
遍历每个 num
从 num 向右扩展
计算当前连续长度 currLen
更新 maxLen = max(maxLen, currLen)
跳过,继续下一个 num
返回 maxLen
- 核心举例:
以 nums = [100, 4, 200, 1, 3, 2] 为例:
| 数字 | 是否为序列起点 | 序列扩展结果 | 序列长度 |
|---|---|---|---|
| 100 | ✅(100-1不在) | [100] | 1 |
| 4 | ❌(3在) | --- | --- |
| 200 | ✅(199不在) | [200] | 1 |
| 1 | ✅(0不在) | [1,2,3,4] | 4 |
最终得到最长连续序列长度 4。
解法二:排序 + 遍历(容易想但性能一般)
步骤:
- 先排序。
- 从前向后统计连续数字段长度。
缺陷: 复杂度 O(n log n),无法满足高性能要求。
复杂度:
- 时间:
O(n log n) - 空间:
O(1)(如果原地排序)
解法三:Union-Find 并查集(可做扩展)
思想是把相邻数字连成一组,最后找最大集合大小。
不过此题用 HashSet 扩展法更优,Union-Find 适合理解"元素连通关系"。
四、复杂度分析
| 方法 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| HashSet 扩展法 | O(n) |
O(n) |
| 排序遍历法 | O(n log n) |
O(1) |
| Union-Find 法 | O(n)(但常数高) |
O(n) |
五、Java 最优解代码实现
java
import java.util.HashSet;
import java.util.Set;
public class Solution {
public int longestConsecutive(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) {
set.add(num);
}
int longest = 0;
for (int num : set) {
// 只从序列起点开始扩展
if (!set.contains(num - 1)) {
int currentNum = num;
int currentStreak = 1;
while (set.contains(currentNum + 1)) {
currentNum++;
currentStreak++;
}
longest = Math.max(longest, currentStreak);
}
}
return longest;
}
}
总结
| 优点 | 缺点 | 适用场景 |
|---|---|---|
| HashSet 扩展法速度快、思路直观 | 需额外 O(n) 空间 | 数组规模大、性能要求高 |
| 排序法实现简单 | 性能稍差 | 面试写得快但不是最优 |
| 并查集法结构更复杂 | 实现冗长 | 理解"连通"类型问题 |