传送门:128. 最长连续序列 - 力扣(LeetCode)
题目:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。
示例 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 <= nums[i] <= 109
解题思路
- 这个题目的核心思路是通过哈希集合(Set)来高效地查找数字是否存在,首先将所有数字存入Set实现去重和O(1)时间复杂度的查找,然后遍历Set中的每个数字,通过检查当前数字x的前一个数字x-1是否存在来判断x是否为某个连续序列的起点,只有当x是序列起点时才向后查找连续的数字序列,这样可以确保每个连续序列只被处理一次而不会重复计算,在查找过程中使用while循环不断检查y+1是否存在来扩展当前序列的长度,最后通过Math.max比较并记录所有序列中的最大长度,这种方法的巧妙之处在于利用哈希集合快速查找的特性避免了排序带来的O(nlogn)时间复杂度,同时通过只从序列起点开始扩展的优化策略将整体时间复杂度控制在O(n),空间复杂度为O(n),是一种既高效又简洁的解决方案。
代码
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function (nums) {
let sum = 0; // 初始化最长序列长度
// 使用Set去重并实现O(1)时间复杂度的查找
const hashset = new Set(nums);
// 遍历集合中的每个数字
for (const x of hashset) {
// 如果存在比x小1的数字,说明x不是序列的起点,跳过
if (hashset.has(x - 1)) {
continue;
}
// 从当前数字x开始,寻找连续序列
let y = x + 1; // 初始化y为x的下一个数字
while (hashset.has(y)) { // 检查y是否存在于集合中
y++; // 存在则继续检查下一个数字
}
// 计算当前序列长度(y-x)并与已知最大值比较
sum = Math.max(sum, y - x);
}
return sum; // 返回最长连续序列的长度
};