题目描述
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
示例:
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
分析
本题的难点在于要求时间复杂度要求为O(n)。
方法一:
使用c++的带排序的set进行求解
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
set<int> myset(nums.begin(), nums.end());
int pre = 0;
int ans = 0;
int r = 0;//表示右指针
int l = 0;//表示左指针
for(auto it:myset){
if(r==0){
pre = it;
ans = 1;
//r++;
}else{
if(it==pre+1){
pre = it;
//对于最后一个元素要特殊处理
if(r==myset.size()-1) ans = max(ans, r+1-l);
}else{
ans = max(ans, r-l);
pre = it;
l = r;
}
}
r++;
}
return ans;
}
};
但是由于使用了带排序的set因此时间复杂度是O(nlogn)。
方法二:
使用不带排序的set:unordered_map。C++ 11中出现了两种新的关联容器:unordered_set和unordered_map,其内部实现与set和map大有不同,set和map内部实现是基于RB-Tree,而unordered_set和unordered_map内部实现是基于哈希表(hashtable),由于unordered_set和unordered_map内部实现的公共接口大致相同,所以本文以unordered_set为例。
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> myset(nums.begin(), nums.end());
int res = 0;
for(auto it:myset){
if(myset.count(it-1)) continue;//当前的it不能作为开头
int cnt = 0;
while(myset.count(it)){
cnt++;
it++;
}
res = max(res, cnt);
}
return res;
}
};