给定一个未排序的整数数组 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是一个序列的起点呢?
我们知道,如果一个数是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
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;
- }
- };