大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。
题目
128. 最长连续序列
给定一个未排序的整数数组 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 <= 105-109 <= nums[i] <= 109
暴力解法
思路
- 对数组进行去重后排序;
- 从索引
1开始遍历,判断当前值是否等于上一个值加一,如果是的话当前的长度加一,如果不是的话当前长度变回1; - 到达每个元素的时候,判断当前的长度和上一轮的最强长度的大小,把最大值作为最长长度;
- 遍历结束后,返回最长长度即可。
实现
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function(nums) {
if (!nums.length) return 0;
// 去重后排序
nums = [...new Set(nums)].sort((a, b) => a - b);
let count = 1, maxCount = 1;
for (let i = 1; i < nums.length; i++) {
// 判断是否连续,是的话长度加一
if (nums[i] === nums[i - 1] + 1) {
count++;
// 判断是否最长长度
maxCount = Math.max(count, maxCount);
} else {
count = 1;
}
}
return maxCount;
};
哈希表
思路
- 先通过
set做去重,同时记录好每个元素是否出现过; - 遍历一轮
set,找到每个Key值往左递减、往右递增的最长顺序,记得找到了的元素在set中移除; - 每次判断完比较一下最长的长度,保留最大值。
实现
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function(nums) {
let set = new Set(nums);
let maxCount = 0;
for (let key of set) {
let cur = key;
let count = 1;
while (set.has(cur - 1)) {
set.delete(cur - 1);
count++;
cur--;
}
cur = key;
while (set.has(cur + 1)) {
set.delete(cur + 1);
count++;
cur++;
}
maxCount = Math.max(maxCount, count);
}
return maxCount;
};
看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。