【算法】【動態規劃篇】第10節:最長連續序列問題(leetcode 128. 最長連續序列)(使用hash表優化空間複雜度)

本期任務:介紹算法中關於動態規劃思想的幾個經典問題

【算法】【動態規劃篇】第1節:0-1揹包問題

【算法】【動態規劃篇】第2節:數字矩陣問題

【算法】【動態規劃篇】第3節:數字三角形問題

【算法】【動態規劃篇】第4節:硬幣找零問題

【算法】【動態規劃篇】第5節:剪繩子問題

【算法】【動態規劃篇】第6節:最低票價問題

【算法】【動態規劃篇】第7節:最長子串問題

【算法】【動態規劃篇】第8節:最大正方形問題

【算法】【動態規劃篇】第9節:乘積最大子數組問題

【算法】【動態規劃篇】第10節:最長連續序列問題


問題來源

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

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

示例:

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

大佬解析

  • 【動態規劃】Python 題解

    • 用哈希表存儲每個端點值對應連續區間的長度
    • 若數已在哈希表中:跳過不做處理
    • 若是新數加入:
      • 取出其左右相鄰數已有的連續區間長度 left 和 right
      • 計算當前數的區間長度爲:cur_length = left + right + 1
      • 根據 cur_length 更新最大長度 max_length 的值
      • 更新區間兩端點的長度值

代碼


"""
需求:
    給定一個未排序的整數數組,找出最長連續序列的長度。
    要求算法的時間複雜度爲 O(n)。
    
思想:
    多趟遍歷法:(內存溢出)
        第一趟,找出數組中的最大和最小元素max_num、min_num,初始化數組,值爲0,[min_num, max_num]
        第二趟,將出現過的位置置爲1
        第三趟,找出最長連續子序列
        
    動態規劃法:
        出於內存考慮,建一個dp_dict,用於存儲以某個點爲端點的最長連續子串長度
        維護一個最大長度值,遍歷每個數字,最終得到最終結果

"""


class Solution:
    def longestConsecutive(self, nums) -> int:
        # 邊界情況處理
        nums = set(nums)
        size = len(nums)
        if size in [0, 1]:
            return size

        hash_dict = dict()
        max_length = 0

        for num in nums:
            left = hash_dict.get(num - 1, 0)
            right = hash_dict.get(num + 1, 0)
            cur_length = left + right + 1
            max_length = max(max_length, cur_length)

            hash_dict[num] = cur_length
            hash_dict[num - left] = cur_length  # 只需關心num-left與num+right,其間的值不會再出現,細品
            hash_dict[num + right] = cur_length

        return max_length

    def longestConsecutive1(self, nums) -> int:
        """三趟遍歷:內存溢出"""
        
        size = len(nums)
        if size in [0, 1]:
            return size

        # 第一趟,找出數組中的最大和最小元素max_num、min_num,初始化數組,值爲0,[min_num, max_num]
        min_num, max_num = min(nums), max(nums)
        res = [0] * (max_num - min_num + 1)

        # 第二趟,將出現過的位置置爲1
        for v in nums:
            res[v - min_num] = 1

        # 第三趟,找出最長連續子序列
        max_length = 0
        tmp = list()
        for i, v in enumerate(res):
            if v == 0:
                max_length = max(len(tmp), max_length)
                tmp = list()
            elif v == 1:
                tmp.append(i + min_num)
        max_length = max(len(tmp), max_length)
        return max_length

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章