128. Longest Consecutive Sequence
題目描述 給定一個未排序的整數陣列 nums,找出其中最長的連續序列(例如 [5, 6, 7, 8])。要求演算法的時間複雜度為 O(n)。 限制條件 * 0 <= nums.length <= 10^5 * -10^9 <= nums[i] <= 10^9 測試用例思考 * 空陣列:[] ⇒ 0 * 無連續序列:[1, 3, 5, 7, 9] ⇒ 1 * 重複數字:[1, 1, 1, 1, 1, 1, 1] ⇒ 1 * 無序的連續序列:[1, 4,
題目描述
給定一個未排序的整數陣列 nums,找出其中最長的連續序列(例如 [5, 6, 7, 8])。要求演算法的時間複雜度為 O(n)。
限制條件
- 0 <= nums.length <= 10^5
- -10^9 <= nums[i] <= 10^9
測試用例思考
- 空陣列:[]⇒0
- 無連續序列:[1, 3, 5, 7, 9]⇒1
- 重複數字:[1, 1, 1, 1, 1, 1, 1]⇒1
- 無序的連續序列:[1, 4, 3, 2, 5]⇒5
解題思路
- 排序法:- 將陣列排序後,遍歷一次計算最長的連續序列長度。
- 缺點:排序的時間複雜度為 O(n log n),不符合題目要求的 O(n)。
 
- 並查集(Union Find):- 將數字視為節點,若數字 a和a+1或a-1存在,則合併到同一個集合。
- 缺點:需要額外的資料結構管理,且時間複雜度較高,約為 O(n log n)。
 
- 將數字視為節點,若數字 
- 雜湊集合(HashSet)法:- 將所有數字存入一個 unordered_set,以方便 O(1) 時間複雜度的查詢。
- 遍歷每個數字,對於每個可能是序列起點的數字,嘗試找到連續序列的長度。
- 優化點:在原始的程式碼中,對每個數字都嘗試向上下擴展,並且在過程中刪除集合中的元素。這樣會導致重複訪問數字,可以進一步優化。
 
- 將所有數字存入一個 
優化後的解法
- 步驟 1:將所有數字存入一個 unordered_set,自動去除重複元素。
- 步驟 2:遍歷集合 num_set中的每個數字num。- 檢查是否為序列的起點:如果 num - 1不在集合中,則num是一個可能的序列起點。
- 擴展序列:- 初始化當前序列長度 currentStreak = 1。
- 不斷檢查 num + 1是否在集合中,若存在,則將currentStreak增加,並繼續檢查下一個數字。
 
- 初始化當前序列長度 
- 更新最大序列長度 longestStreak。
 
- 檢查是否為序列的起點:如果 
- 為何這樣可以達到 O(n) 時間複雜度:- 每個數字只會被訪問兩次:一次是作為起點檢查 num - 1,一次是在序列擴展時檢查num + 1。
 
- 每個數字只會被訪問兩次:一次是作為起點檢查 
程式碼
class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> s(nums.begin(), nums.end());
        int ans = 0;
        for (const auto num : nums) {
            if (s.find(num) == s.end()) {
                continue;
            }
            int l = num - 1;
            while (s.find(l) != s.end()) {
                s.erase(l);
                l -= 1;
            }
            int u = num + 1;
            while (s.find(u) != s.end()) {
                s.erase(u);
                u += 1;
            }
            s.erase(num);
            ans = max(ans, u - l - 1);
        }
        return ans;
    }
};
時間與空間複雜度分析
- 時間複雜度:O(n)- 分析:- 將數字插入 unordered_set的時間複雜度為 O(n)。
- 外層迴圈遍歷集合中的每個數字,內層迴圈在擴展序列時,每個數字最多被訪問一次。
- 整體而言,每個數字最多被訪問兩次,因此總的時間複雜度為 O(n)。
 
- 將數字插入 
 
- 分析:
- 空間複雜度:O(n)- 分析:- 使用了額外的 unordered_set來儲存數字,大小為 n。
 
- 使用了額外的 
 
- 分析:
 
                        
Comments ()