目录
一、题目描述
给定一个无序的整数类型数组,要求找出最长的连续元素序列的长度,并且需要给出时间复杂度在 O(n) 之内的算法。
示例 :输入:[1000, 4, 2000, 1, 3, 2],返回值:4(最长连续元素序列为 [1, 2, 3, 4])。
二、解题思路
采用哈希集合 + 遍历起点的方法:
- 首先将数组中的所有元素存入哈希集合,以便快速判断一个元素是否存在。
- 遍历集合中的每个元素,仅当该元素是某连续序列的起点(即
n-1不存在于集合中)时,才向后遍历寻找连续的元素,统计该连续序列的长度。 - 维护一个最大值,记录所有连续序列长度的最大值,最终返回该最大值。
三、代码实现
import java.util.*;
public class Solution {
public int longestConsecutive(int[] num) {
if (num == null || num.length == 0) {
return 0;
}
Set<Integer> set = new HashSet<>();
// 将数组元素存入哈希集合,用于快速查找
for (int n : num) {
set.add(n);
}
int maxLen = 0;
for (int n : set) {
// 只处理连续序列的起点(即n-1不存在的情况)
if (!set.contains(n - 1)) {
int current = n;
int currentLen = 1;
// 向后找连续的元素
while (set.contains(current + 1)) {
current++;
currentLen++;
}
// 更新最长连续序列长度
maxLen = Math.max(maxLen, currentLen);
}
}
return maxLen;
}
// 测试方法
public static void main(String[] args) {
Solution solution = new Solution();
int[] num = {1000, 4, 2000, 1, 3, 2};
System.out.println("最长连续元素序列长度:" + solution.longestConsecutive(num));
}
}
四、代码解释
- 边界处理 :若数组为
null或长度为 0,直接返回 0。 - 初始化哈希集合 :将数组中的所有元素存入
HashSet,利用哈希集合的contains方法在 O(1) 时间内判断元素是否存在。 - 遍历寻找连续序列起点 :对于集合中的每个元素
n,如果n-1不存在于集合中,说明n是某连续序列的起点。 - 统计连续序列长度 :从起点
n开始,向后遍历(current + 1),直到元素不存在于集合中,统计该连续序列的长度currentLen。 - 更新最大值 :每次统计完一个连续序列的长度后,更新
maxLen为当前maxLen和currentLen中的较大值。
五、复杂度分析
- 时间复杂度:O(n)。虽然外层有一个循环遍历集合,内层还有一个 while 循环,但每个元素最多被访问两次(一次在判断是否为起点时,一次在向后遍历连续元素时),所以总的时间复杂度是 O(n)。
- 空间复杂度:O(n)。哈希集合需要存储数组中的所有元素,空间复杂度为 O(n)。