题目
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入:nums = 100,4,200,1,3,2
输出:4
解释:最长数字连续序列是 1, 2, 3, 4。它的长度为 4。
示例 2:
输入:nums = 0,3,7,2,5,8,4,6,0,1
输出:9
示例 3:
输入:nums = 1,0,1,2
输出:3
提示:
0 <= nums.length <= 105
-109 <= numsi <= 109
题解
class Solution {
public int longestConsecutive(int[] nums) {
Set<Integer> nums_set = new HashSet<Integer>();
for(int num : nums){
nums_set.add(num);
}
int maxLength = 0;
for(int num : nums_set){
if(!nums_set.contains(num - 1)){
int currentNum = num;
int currentLength = 1;
while(nums_set.contains(currentNum + 1)){
currentNum += 1;
currentLength +=1;
}
maxLength = Math.max(currentLength,maxLength);
}
}
return maxLength;
}
}
思路
核心思想:寻找"连续序列的起点"
如果我们要找连续序列,比如 1, 2, 3, 4,我们不需要从 2、3 或 4 开始往后数,我们只需要从序列的起点(即 1)开始往后数即可。
如何判断一个数字是起点?
如果 num 是起点,那么它的前一个数字 num - 1 一定不在数组中。
这个判断条件完美地避免了重复计算,保证了算法的 O(n) 复杂度。
步骤
第一步:哈希去重(预处理)
将数组中的所有元素存入 HashSet。这一步不仅自动去除了重复元素,还将后续查找某个数字是否存在的时间复杂度降为了 O(1) 。
第二步:寻找起点
遍历哈希表中的每一个数字 num。通过判断 num - 1 是否存在于集合中,来确认 num 是否为一个连续序列的起点。
第三步:向后延伸并更新最大值
一旦确认 num 是起点,就进入 while 循环,不断检查 num + 1、num + 2... 是否存在,同时累加当前序列长度。遍历结束后,用该长度更新全局最长长度 maxLength。