↓快轉到主要內容
  1. LeetCode/

LeetCode 1696: Jump Game VI

·2 分鐘· ·
LeetCode Medium Dynamic-Programming Monotonic-Queue Queue Heap
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2025-08-10

  • 提交紀錄:Wrong Answer → Time Limit Exceeded → Accepted

解題思路
#

dp[i] = 從 index 0 走到 i 的最大分數。前一步只能是 i - k 到 i - 1 之間:

dp[i] = nums[i] + max(dp[i - k], ..., dp[i - 1])

直接算是 O(nk),n、k 都到 10^5 會超時。前 k 個的最大值是滑動視窗最大值,用單調佇列維護:

  1. 頭端的 index < i - k 丟掉(過期)。
  2. dp[i] = nums[i] + dp[頭端]。
  3. 尾端 dp 值 <= dp[i] 的丟掉(被支配),放入 i。

我的嘗試
#

  1. 第一版 WA:用 dp[i + 1] 表示走到 i、dp[0] = 0,但轉移範圍讓前 k 格都能從 dp[0] 直接跳過來,等於可以不從 index 0 出發。例如 nums = [-1, 5]、k = 2:一定要經過 -1,答案是 4,這版回傳 5。
  2. 第二版 TLE:改成 dp[0] = nums[0],邏輯對了,但雙層迴圈 O(nk)。
  3. AC:換成單調佇列。

正確解法
#

from collections import deque

class Solution:
    def maxResult(self, nums: List[int], k: int) -> int:
        n = len(nums)
        dp = [0] * n
        dp[0] = nums[0]                            # 一定從 index 0 出發
        dq = deque([0])                            # index,dp 值遞減
        for i in range(1, n):
            if dq[0] < i - k:
                dq.popleft()                       # 過期
            dp[i] = nums[i] + dp[dq[0]]
            while dq and dp[dq[-1]] <= dp[i]:
                dq.pop()                           # 被 dp[i] 支配
            dq.append(i)
        return dp[-1]

我 AC 的版本是在算完 dp[i] 之後才檢查過期(dq[0] <= i - k),等於提前一步把下一輪會過期的丟掉,結果一樣;先檢查再取值比較直覺。

複雜度
#

時間 O(n),空間 O(n)。

要特別避免的錯誤
#

  • 起點一定是 index 0:dp[0] = nums[0],不是 0。
  • O(nk) 的雙層迴圈會超時。

面試口說整理
#

dp[i] 是走到 i 的最大分數,等於 nums[i] 加上前 k 個 dp 的最大值。前 k 個的最大值是滑動視窗最大值,我用單調佇列維護:頭端丟過期的、尾端丟被新值支配的,頭端就是最大值。每個 index 進出一次,時間 O(n)。

相關文章

LeetCode 3638: Maximum Balanced Shipments
·1 分鐘
LeetCode Medium Dynamic-Programming Greedy Monotonic-Stack Array
LeetCode 3638 解題筆記:貪心,一段一旦出現比這段最大值小的數就馬上切;因為切之前的那段是非遞減的,最大值就是前一個數
LeetCode 3607: Power Grid Maintenance
·2 分鐘
LeetCode Medium Heap Union-Find Graph Lazy-Deletion
LeetCode 3607 解題筆記:Union-Find 分群,每群一個 min-heap,離線的站用 lazy deletion
LeetCode 3508: Implement Router
·2 分鐘
LeetCode Medium Design Binary-Search Queue Hash-Map
LeetCode 3508 解題筆記:queue 管 FIFO、set 判重複、每個目的地一個遞增的時間陣列,查詢用 bisect
LeetCode 1353: Maximum Number of Events That Can Be Attended
·1 分鐘
LeetCode Medium Heap Greedy Sorting
LeetCode 1353 解題筆記:每天參加「最早結束」的活動,用 min-heap 存結束日
LeetCode 313: Super Ugly Number
·1 分鐘
LeetCode Medium Array Math Dynamic-Programming
LeetCode 313 解題筆記:LC 264 的推廣,每個質數一個指針;用 heap 的話要避免同一個數被推進去很多次
LeetCode 337: House Robber III
·1 分鐘
LeetCode Medium Dynamic-Programming Tree Depth-First-Search Binary-Tree
LeetCode 337 解題筆記:樹上 DP,每個節點回傳(搶它、不搶它)的最大值;不是一層一層交錯搶