題目
給定一個未排序的整數數組,找出最長連續序列的長度。要求算法的時間複雜度爲 O(n)。
示例:
輸入: [100, 4, 200, 1, 3, 2] 輸出: 4
解釋: 最長連續序列是 [1, 2, 3, 4]。它的長度爲 4。
思路分析
總共三種方法可以解決。
- 思路一:對數組進行排序,然後統計連續的元素即可。時間複雜度O(nlogn)。時間複雜度主要受排序影響。
- 思路二:使用哈希表記錄元素是否被使用。對每個元素,以該元素爲中心,往左右擴展,在哈希表中查找相應擴展元素。時間複雜度O(n^2)。
- 思路三:目前只能給出相應代碼,思路還不能理解。
思路一
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if(nums.size()==1||nums.size()==0) return nums.size();
sort(nums.begin(),nums.end());
int length=0;
for(int i=1;i<nums.size();i++)
{
if(nums[length]!=nums[i]){
nums[++length]=nums[i];
}
}
int countLength=1;
int longest=countLength;
for(int i=1;i<=length;i++){
if(nums[i]==nums[i-1]+1){
countLength++;
longest=max(longest,countLength);
}else{
countLength=1;
}
}
return longest;
}
};
思路二
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_map<int,bool> used;
for(int i:nums) used[i]=false;
int longest=0;
for(auto i:nums){
if(used[i]) continue;
int length=1;
used[i]=true;
for(int j=i+1;used.find(j)!=used.end();++j){
used[j]=true;
++length;
}
for(int j=i-1;used.find(j)!=used.end();--j){
used[j]=true;
++length;
}
longest=max(longest,length);
}
return longest;
}
};
思路三
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_map<int,int> map;
int size=nums.size();
int l=1;
for(int i=0;i<size;i++){
if(map.find(nums[i])!=map.end()) continue;
map[nums[i]]=1;
if(map.find(nums[i]-1)!=map.end()){
l=max(l,mergeCluster(map,nums[i]-1,nums[i]));
}
if(map.find(nums[i]+1)!=map.end()){
l=max(l,mergeCluster(map,nums[i],nums[i]+1));
}
}
return size==0?0:l;
}
private:
int mergeCluster(unordered_map<int,int> &map,int left,int right){
int upper=right+map[right]-1;
int lower=left-map[left]+1;
int length=upper-lower+1;
map[upper]=length;
map[lower]=length;
return length;
}
};