题目
给定一个未排序的整数数组 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
解法
哈希表@LeetCode林小鹿
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> hash;
for(auto x : nums)
hash.insert(x);
int res = 0;
for(auto x : hash)
{
if(!hash.count(x-1)) // 如果x-1存在,说明当前数x不是连续序列的起始数字,我们跳过这个数。
{
int y = x;
while(hash.count(y + 1))
y++;
res = max(res, y - x + 1); //更新答案
}
}
return res;
}
};
时间复杂度分析: for循环套while循环的代码,不能想当然的认为两层循环时间复杂度就是O(n^2)的,具体要看内循环while的执行次数。对于此题,不是每次for循环,while中都要执行n次,而是对于整个for循环,while最多执行n次,while中是以当前数x向后枚举,不是从开头开始枚举的,因此平均到每次for循环就是一次,所以总的时间复杂度为O(n)。
数组排序
注意:sort(nums.begin(), nums.end()); 时间复杂度是O(nlogn),AC能过,但是不符合题目要求
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if (nums.size() == 0)
return 0;
int ans = 1, num = 1;
sort(nums.begin(), nums.end());
for(int i=1; i<nums.size(); i++)
{
if(nums[i] == (nums[i-1]+1))
ans ++;
else if(nums[i] == nums[i-1]) // 直接sort不会排除重复元素
continue;
else
{
num = max(ans, num);
ans = 1;
}
}
return max(ans, num);
}
};