LeetCode 面試題☞最長連續序列

題目描述

  • 題目

給定一個未排序的整數數組,找出最長連續序列的長度。

  • 要求算法的時間複雜度爲 O(n)。

  • 示例:

      輸入: [100, 4, 200, 1, 3, 2]
      輸出: 4
      解釋: 最長連續序列是 [1, 2, 3, 4]。它的長度爲 4。
    

解題

數組形式

  • 遍歷整個數組,並調用函數判斷與目標數連續序列的長度
  • 需要對遍歷過程中的重複數字進行處理,避免長度計算錯誤
  • 循環上述步驟,直到遍歷結束

image.png

代碼實現

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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章