LeetCode 128. 最長連續序列 | Python

128. 最長連續序列


題目


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

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

示例:數組

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

解題思路


思路:哈希表spa

本題主要的難點在於算法時間複雜度限定爲 O(n) 的方法上。code

先假設通常的狀況下。能夠嘗試枚舉數組中每一個元素 i,以其起點不斷嘗試匹配 +1,+2 ... 是否存在於數組中,這樣不斷枚舉並更新最大的長度。固然,這樣會很是消耗時間,由於當你枚舉 i 結束時,再次遇到元素值 i+1 時,這裏又將從新匹配。(考慮改進)blog

能夠考慮使用集合的方法,先使用集合,將數組去重。這裏須要改進的就是重複匹配的狀況。排序

當使用集合的方法時,這裏先說明一下,在什麼樣的狀況下才要去開始計算長度,而不須要重複去匹配。若是 i 的前面一個數 i-1 存在於集合當中,那麼它在這個時候就須要被跳過。由於它與 i 是能夠組成連續序列的,只要在 i-1 的時候計算便可。rem

那麼也就是,當 i 存在前驅數 i-1 的時候,不須要計算,直接跳過。只有當 i 無前驅數時,才能夠當成是起始的位置開始計算長度。遍歷匹配不斷更新最大值便可。(具體代碼就不貼了,這裏給出大概的思路,可嘗試編寫)get

如今主要介紹本篇幅使用的哈希表的方法。

這裏哈希表的鍵是每一個端點,而值則是它對應連續區間的長度。

具體的作法:

  • 構建哈希表,遍歷數組;
  • 若是數已經存在於哈希表中,那麼跳過不作處理;
  • 若是數是新數的狀況下,那麼這裏新數將須要查找左右相鄰數對應的值(也就是左右相鄰數字對應的連續區間的長度)。這裏與當前數的長度相加就是這個數對應的新區間長度。length = left + 1 + right
  • 須要與最大的長度值進行比較,更新最大值
  • 同時還須要更新兩個端點的區間長度值。

具體的代碼實現以下。

代碼實現


class Solution:
    def longestConsecutive(self, nums: List[int]) -> int:
        hash_dict = {}

        max_length = 0

        for num in nums:
            # 這裏表示新數進來
            # 此時須要查找左右相鄰的兩個數對應的區間長度
            # 左右兩個數的長度 + 自身的長度,就是此時新數對應的區間長度
            if num not in hash_dict:
                # 若是鍵不在哈希表中,取值 0
                pre_length = hash_dict.get(num - 1, 0)
                next_length = hash_dict.get(num + 1, 0)

                cur_length = pre_length + 1 + next_length
                
                if cur_length > max_length:
                    max_length = cur_length
                
                # 添加新數,同時更新兩個端點的值
                # 由於序列是連續的,此時兩側端點對應的區間長度會由於當前數的加入發生改變
                hash_dict[num] = cur_length
                hash_dict[num-pre_length] = cur_length
                hash_dict[num+next_length] = cur_length
        
        return max_length

實現結果


實現結果

總結


  • 本篇幅使用的是哈希表的方法。哈希表的 key 存的是端點,而 value 存儲的端點對應的連續區間長度。
  • 具體的實現的作法:

    • 構建哈希表,遍歷數組
    • 當遇到存在於哈希表的數字,不作處理跳過
    • 當遇到新數時,須要查找左右相鄰的數對應的區間長度,與自身長度相加。(左右數字不存在於哈希表中,返回 0),與最大值比較同時更新最大值。
    • 將新數與其對應的區間長度存入哈希表中,同時更新左右兩個端點的值。(例如左邊數對應的連續區間長度的起始位置,便是 num - pre_length。num 表示當前數,pre_length 便是左邊的連續區間長度,)
    • 最終返回最大值。

文章原創,若是以爲寫得好,歡迎關注。微信公衆號《書所集錄》同步更新,一樣歡迎關注。
相關文章
相關標籤/搜索