持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情
给定一个未排序的整数数组 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
提示:
0 <= nums.length <= 10^5-10^9 <= nums[i] <= 10^9
思路
看到这道题,第一反应就是排序后遍历求解,方法简单,但是并不符合题目时间复杂度为O(n) 的要求,参照解法一。
本题的难点在于如何使用O(1)的时间判断nums[i]的下一个连续数组nums[i] + 1是否也在数组nums中,首先想到的使用map来存储nums中的数字,然后遍历map,参照解法二。解法三用set代替map是一种讨巧的解法,借助set构造函数省去了map中遍历存储nums的步骤,思路是一样的。
解题
解法一
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function (nums) {
const n = nums.length;
if (n <= 1) return n;
nums.sort((a, b) => a - b);
let res = 1;
let count = 1
for (let i = 1; i < nums.length; i++) {
const diff = nums[i] - nums[i - 1];
if (diff === 1) {
count++;
} else if (diff > 1) {
res = Math.max(count, res);
count = 1;
}
}
return Math.max(count, res);
};
解法二
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function (nums) {
const n = nums.length;
if (n <= 1) return n;
const map = new Map();
let res = 1;
for (let i = 0; i < n; i++) {
map.set(nums[i], 1);
}
for (let num of map.keys()) {
if (map.has(num - 1)) {
continue;
}
let count = 1;
while (map.has(num + count)) {
count++;
}
res = Math.max(count, res);
}
return res;
};
解法三
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function (nums) {
const n = nums.length;
if (n <= 1) return n;
const set = new Set(nums);
let res = 1;
for (let i of set) {
if (set.has(i - 1)) {
continue;
}
let count = 1;
while (set.has(i + count)) {
count++;
}
res = Math.max(count, res);
}
return res;
};