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

LeetCode 1186: Maximum Subarray Sum with One Deletion

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

基本資料
#

難易度: medium 第一次嘗試:2026-10-22

  • 提交紀錄:Wrong Answer → Accepted

解題思路
#

Kadane(Kadane’s Algorithm)多一個狀態。對每個位置 i,記兩個值,都是「子陣列結尾在 i」:

  • no_delete:沒刪過元素的最大和。max(no_delete + num, num),和一般 Kadane 一樣。
  • delete_one:剛好刪過一個元素的最大和。兩種來源:
    • 刪掉現在這個 num:前面沒刪過的子陣列,和是上一步的 no_delete。
    • 之前已經刪過:delete_one + num。

兩個值要用上一步的值同時更新。子陣列至少要留一個元素,delete_one 從 -inf 開始,第一個元素不能被刪成空的。

答案是所有位置的兩個值裡的最大值,每一步都要更新。

我的嘗試
#

  1. 只在最後回傳 max(no_delete, delete_one)。但這兩個狀態只代表「結尾在最後一個元素」的子陣列,最佳答案可能更早就結束了:[1,-1,-3] 回傳 0,答案是 1。
  2. 每一步都更新答案就過了。

正確解法
#

class Solution:
    def maximumSum(self, arr: List[int]) -> int:
        no_delete = -inf
        delete_one = -inf
        best = -inf
        for num in arr:
            no_delete, delete_one = max(no_delete + num, num), max(no_delete, delete_one + num)
            best = max(best, no_delete, delete_one)
        return best

複雜度
#

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

要特別避免的錯誤
#

  • DP 狀態是「結尾在這裡」,答案要在每一步取最大,不是只看最後一步。
  • 兩個狀態要同時更新(tuple 賦值),delete_one 要用舊的 no_delete。
  • 全部是負數時答案是最大的那個元素,不能刪成空陣列,所以初始值用 -inf 不是 0。

面試口說整理
#

這是 Kadane 多一個狀態:結尾在 i、沒刪過的最大和,和結尾在 i、刪過一個的最大和。刪過一個的來源有兩種:刪掉現在這個,接上一步沒刪過的;或之前已經刪過,加上現在這個。因為狀態是「結尾在這裡」,答案要在每一步更新。時間 O(n),空間 O(1)。

相關文章

LeetCode 3638: Maximum Balanced Shipments
·1 分鐘
LeetCode Medium Dynamic-Programming Greedy Monotonic-Stack Array
LeetCode 3638 解題筆記:貪心,一段一旦出現比這段最大值小的數就馬上切;因為切之前的那段是非遞減的,最大值就是前一個數
LeetCode 313: Super Ugly Number
·1 分鐘
LeetCode Medium Array Math Dynamic-Programming
LeetCode 313 解題筆記:LC 264 的推廣,每個質數一個指針;用 heap 的話要避免同一個數被推進去很多次
LeetCode 396: Rotate Function
·1 分鐘
LeetCode Medium Array Math Dynamic-Programming
LeetCode 396 解題筆記:F(k) 和 F(k - 1) 只差一個公式:F(k) = F(k - 1) + sum - n × 被移到最前面的那個數
LeetCode 435: Non-overlapping Intervals
·1 分鐘
LeetCode Medium Array Dynamic-Programming Greedy Sorting
LeetCode 435 解題筆記:最少刪幾個 = 總數減掉最多能保留幾個;按右端點排序,貪心保留結束最早的
LeetCode 473: Matchsticks to Square
·1 分鐘
LeetCode Medium Array Dynamic-Programming Backtracking Bit-Manipulation
LeetCode 473 解題筆記:總和要能被 4 整除;由大到小把每根火柴放進四個邊之一,超過邊長或跟前一個邊長度相同就跳過
LeetCode 4040: Minimum Operations to Form Subset Sum I
·2 分鐘
LeetCode Medium Dynamic-Programming Knapsack Array
LeetCode 4040 解題筆記:先乘後除時,最佳的做法只會是「只乘」或「只除」;列出每個數能變成的值和步數,再做分組 0/1 背包