128. 最长连续序列 - 力扣(LeetCode)
问题描述
给定一个未排序的整数数组 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
题解
如何判断连续序列
假如x是一个连续序列的起点,那么如果这个连续序列存在于nums中,那么只需要判断x,x+1,x+2,x+3,...,x+n都是否存在于nums中即可,如果这些数字都存在于nums中,那么n+1就是我们返回的结果
判断一个数是否存在于nums中,显然我们可以使用一个哈希表存储nums中的数,因为在哈希表中判断一个数是否存在的时间复杂度为O(1)
因此由上述思路,我们可以得到一个解法,枚举nums中每一个数x,判断x之后的x+1,x+2,x+3,...,x+n是否在哈希表中,最后返回结果即可。
但是还有一个问题是,如何判断我们遍历nums时枚举的数x是一个序列的起点呢?
判断枚举的数x是否是一个序列的起点
我们知道,如果一个数是nums中一个连续序列的起点数字,那么x-1,必然不存在于nums中,而我们已经使用了一个哈希表来存储nums中的所有数,因此我们只需要在枚举的时候判断x-1是否存在于哈希表中即可,如果x-1存在于哈希表中,那么该数就不是nums中连续序列的起点,跳过即可,否则就判断其后的数字是否存在,并返回结果
代码整体思路
故代码整体思路为:
- 使用一个set存储nums中的所有数(使用set可以去重)
- 遍历nums,判断nums[i]-1是否存在于set中
- 如果num[i]-1存在与set中,说明nums[i]不是一个连续序列的起点,跳过
- 否则说明num[i]是我们要找的某一个连续序列的起点,接下来判断nums[i]的每一个数是否存在于set中,也就是判断一个连续序列是否存在,并记录连续序列的长度
- 更新最大连续序列的长度(因为每次找到的连续序列长度不一定是最大的,需要判断)
代码
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> ms;
//去重
for(int num:nums)
ms.insert(num);
int res=0;
for(int i=0;i<nums.size();i++)
{
//说明当前元素是一个连续序列的起始位置
if(!ms.count(nums[i]-1))
{
int curNum=nums[i];
int curSeq=1;//记录当前序列长度
while(ms.count(curNum+1))//判断连续序列是否存在
{
curNum++;
curSeq++;
}
res=max(res,curSeq);//更新最长序列长度
}
}
return res;
}
};