一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情
题目(Longest Consecutive Sequence)
链接:https://leetcode-cn.com/problems/longest-consecutive-sequence
解决数:1535
通过率:54.8%
标签:并查集 数组 哈希表
相关公司:google amazon bytedance
给定一个未排序的整数数组 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
思路
- 先使用快速排序,得到有序数组。
- 声明一个对象obj,来存放队列。key是当前元素arr[0],value是个数组,初始化只存放一个当前元素arr[0]
- 使用临时变量记录该队列
- 遍历数组: a. 如果差值等于1,则给队列push当前元素; b. 如果差值为0,继续; c. 如果差值不为0,当前队列结束,启动下一个队列。key是当前元素arr[i],value是个数组,初始化只存放一个当前元素arr[i]
- 最后得到obj为 { '1': [ 1, 2, 3, 4 ], '100': [ 100 ], '200': [ 200 ] }
- Object.values(obj)得到[ [ 1, 2, 3, 4 ], [ 100 ], [ 200 ] ]
- .map(arr => arr.length)得到 [4, 1, 1]
- 最后Math.max(...[4, 1, 1])得到最大值
事件复杂度 O(nlogn)
快速排序:O(nlogn) for循环: O(n)
代码
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function(nums) {
if (nums.length === 0) return 0
const arr = nums.sort((a, b) => a - b)
const obj = {}
obj[arr[0]] = [arr[0]]
let temp = obj[arr[0]]
for (let i = 1; i < arr.length; i++) {
const diff = arr[i] - temp[temp.length - 1]
if (diff === 1) {
temp.push(arr[i])
} else if (diff === 0) {
continue
} else {
obj[arr[i]] = [arr[i]]
temp = obj[arr[i]]
}
}
return Math.max(...Object.values(obj).map(arr => arr.length))
};
思路2
- 要求算法的时间复杂度为 O(n),即限制了只能循环一次;
- 先对数组排序
- 循环数组记录后一个元素等于前一个元素+1或者等于前一个元素的数量
- 满足条件++,不然重置
- 与之前记录的值取最大值
- 个人觉得和题目的限制,虽然排序是用数组原生的方法做的,但是应该是多了一次排序的循环
/**
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function (nums) {
if (nums.length < 2) return nums.length;
var _result = 1, middleValue = 1;
nums.sort((a, b) => a - b)
for (let index = 0; index < nums.length; index++) {
if (nums[index] === nums[index + 1]) {
continue // 跳出本次循环
} else if (nums[index] + 1 === nums[index + 1]) {
middleValue++
} else {
middleValue = 1
}
_result = Math.max(_result, middleValue);
}
return _result;
};