題目描述
- 題目
給定一個未排序的整數數組,找出最長連續序列的長度。
-
要求算法的時間複雜度爲 O(n)。
-
示例:
輸入: [100, 4, 200, 1, 3, 2] 輸出: 4 解釋: 最長連續序列是 [1, 2, 3, 4]。它的長度爲 4。
解題
數組形式
- 遍歷整個數組,並調用函數判斷與目標數連續序列的長度
- 需要對遍歷過程中的重複數字進行處理,避免長度計算錯誤
- 循環上述步驟,直到遍歷結束
代碼實現
class Solution {
public:
int MaxLength(vector<int> & v,int begin){
int end=begin+1;
int start=begin;
int flag=0;
while(end<v.size()){
if(v[start]==v[end]-1 ){
start=end;
end++;
}else if(v[start]==v[end]){
//記錄重複數字的個數
start=end;
end++;
++flag;
}else{
break;
}
}
return end-begin-flag;//返回的是去重之後的結果
}
int longestConsecutive(vector<int>& nums) {
if(nums.empty()){
return 0;
}
sort(nums.begin(),nums.end());
int length=0;
int index=0;
int flag=1;
while(index<nums.size()){
if(flag==1){
//該判斷是爲了將第一次調用函數的長度設定爲最長長度
length=MaxLength(nums,index);
index+=length;
flag=0;
}else{
int max=MaxLength(nums,index);
index+=max;//更新到下一個目標數
if(max>length){
length=max;
}
}
}
return length;
}
};
改進版本
- 減少一個判斷,使用了函數max();
class Solution {
public:
int MaxLength(vector<int> & v,int begin){
int end=begin+1;
int start=begin;
int flag=0;
while(end<v.size()){
if(v[start]==v[end]-1 ){
start=end;
end++;
}else if(v[start]==v[end]){
start=end;
end++;
++flag;
}else{
break;
}
}
return end-begin-flag;
}
int longestConsecutive(vector<int>& nums) {
if(nums.empty()){
return 0;
}
sort(nums.begin(),nums.end());
int length=0;
int index=0;
int flag=1;
while(index<nums.size()){
int max_len=MaxLength(nums,index);
index+=max_len;
length=max(length,max_len);
}
return length;
}
};
哈希表
- 將數組中的元素存儲到哈希表中,該過程達到了去重的目的
- 開始遍歷哈希表,記錄其中最長連續序列的長度
在遍歷的過程中,若存在比目標數小 1 1的數,則目標數不是和當連續序列的開頭繼續循環
若不存在比目標數小 1 的數,說明該數可以當作連續序列的開頭.並計算其連續序列的長度
代碼
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> st;
for(int n: nums) st.insert(n);
int ans = 0;
for(int i: st){
// 假如一個數在哈希表中存在比他小的,那麼它不是可以作爲開頭的數字
if(i != INT_MIN && st.count(i-1)){
continue;
}
int cnt = 1;
while(i!=INT_MAX && st.count(i+1)){
//記錄有序序列的長度
cnt ++;
i++;
}
ans = max(ans, cnt);
}
return ans;
}
};