問題描述
給定一個未排序的整數數組,找出最長連續序列的長度。
要求算法的時間複雜度爲
解題報告
- 暴力查找
最粗暴的想法,從每個數字出發,依次查找後面能達到的最長連續序列長度。加上一點優化:判斷一個數 x 是否是某個連續序列的開頭,首先判斷 x-1 是否在數組中。 - 並查集
將任意相差爲1的兩個數相連,當將數組遍歷完,我們得到若干子樹,節點數最大的那棵子樹的節點數即爲答案。
實現代碼
- 暴力查找
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_map<int,int>mp;
for(auto num:nums) mp[num]=1;
int ans=0;
for(int i=0;i<nums.size();i++){
if(mp.count(nums[i]-1)) continue;
int y=nums[i]+1;
while(mp.count(y)){
y++;
}
ans=max(ans,y-nums[i]);
}
return ans;
}
};
- 並查集
class Solution{
public:
unordered_map<int,int>fa,cnt;
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int merge(int x,int y){
x=find(x);
y=find(y);
if(x==y) return cnt[x];
fa[y]=x;
cnt[x]+=cnt[y];
return cnt[x];
}
int longestConsecutive(vector<int>&nums){
if(nums.size()==0){
return 0;
}
for(auto num:nums){
fa[num]=num;
cnt[num]=1;
}
int ans=1;
for(auto num:nums){
if(fa.count(num+1)){
ans=max(ans,merge(num,num+1));
}
}
return ans;
}
};