题目描述
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例:
输入: nums = [100,4,200,1,3,2]
输出: 4
解释: 最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
提示:
0 <= nums.length <= 105-109 <= nums[i] <= 109
题解
分析题目,一般的解法为
sort进行排序
for循环遍历数组,进行连续序列的数量计数
取最大数返回
然而这种解法,sort排序的时间复杂度为O(nlogn),不符合题目要求
所以不能使用sort排序
采用哈希集合Set
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function(nums) {
const st = new Set(nums);
let ans = 0;
for (x of st){
if (st.has(x-1)) continue;
let y =x+1;
while(st.has(y)){
y++;
}
ans = Math.max(ans,y-x);
if (ans * 2 >= st.size){
break;
}
}
return ans;
};
通过将数组转换为 Set,来实现 O(1) 的快速查找和去重。
遍历集合,并使用 if (st.has(x-1))来确保只有序列的起点 x 才被处理,避免了对序列中其他元素的重复计算。一旦找到起点,就用 while 循环不断递增 y 来找出序列的终点,通过 y−x 计算长度并更新最大值 ans。
另外,末尾的 if (ans * 2 >= st.size) break; 使算法在最大长度已确定的情况下提前退出循环(即连续序列为数组长度一半时,不可能再有更长的连续序列)。
时间,空间复杂度
时间复杂度 O(N)
Set 初始化 O(N)。遍历和 while 循环的总操作次数也为 O(N)。
空间复杂度 O(N)
使用了一个 Set 来存储最多 N 个唯一的数字。