最长连续序列
给定一个未排序的整数数组 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
Set查找
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function(nums) {
const numSet= new Set(nums)
let maxLength=0
for(let num of nums){
if(!numSet.has(num-1)){
let current=num
let length=1
while(numSet.has(current+1)){
current++
length++
}
maxLength = Math.max(maxLength,length)
}
}
return maxLength
}
-
Set操作虽然理论 O(1),但哈希冲突、扩容等因素会增加常数时间; -
如果数字范围非常大(比如几百万,几千万),单次
while循环会产生大量连续查询,CPU 缓存和内存访问效率降低。使用这个方法LeeCode不通过,会给超时警告。
哈希表+动态区间
/**
* @param {number[]} nums
* @return {number}
*/
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function(nums) {
let map=new Map(),maxCount=0
for (let num of nums) {
if (!map.has(num)) {
const leftLen = map.get(num - 1) || 0;
const rightLen = map.get(num + 1) || 0;
const curLen = leftLen + 1 + rightLen;
map.set(num, curLen);
// 更新左边界
map.set(num - leftLen, curLen);
// 更新右边界
map.set(num + rightLen, curLen);
maxCount = Math.max(maxCount, curLen);
}
}
return maxCount
}