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

LeetCode 3952: Maximum Total Value of Covered Indices

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

基本資料
#

難易度: medium 第一次嘗試:2026-06-11

  • 提交紀錄:Accepted(一次通過)

解題思路
#

每個代幣最多往左移一格,所以第 i 格的代幣只會影響第 i - 1 和第 i 格。從左到右做狀態機 DP,狀態是第 i 格的代幣有沒有往左移:

  • stay:處理完前 i 格,第 i 格的代幣留在原地(或第 i 格沒有代幣)的最大值。
  • move:處理完前 i 格,第 i 格的代幣移到了 i - 1 的最大值。

轉移到第 i 格:

  • 沒有代幣:兩個狀態一樣,都是 max(move, stay)。
  • 有代幣、留在原地:max(move, stay) + nums[i]。
  • 有代幣、往左移:第 i - 1 格會被蓋住,但它可能本來就被蓋住了:
    • 如果 i - 1 也有代幣,只有當那個代幣往左移走了(move 狀態),蓋住它才有用:move + nums[i - 1]。
    • 如果 i - 1 沒有代幣,它原本一定沒被蓋:max(move, stay) + nums[i - 1]。

所有數都是正的,所以不用考慮「拿了反而更差」的情況。

我的解法
#

class Solution:
    def maxTotal(self, nums: List[int], s: str) -> int:
        move = float("-inf")                       # 第 0 格的代幣不能往左
        stay = nums[0] if s[0] == "1" else 0
        for i in range(1, len(nums)):
            best = max(move, stay)
            if s[i] == "1":
                new_stay = best + nums[i]
                if s[i - 1] == "1":
                    new_move = move + nums[i - 1]  # 左邊的代幣移走了,這格才空出來
                else:
                    new_move = best + nums[i - 1]
            else:
                new_stay = new_move = best
            move, stay = new_move, new_stay
        return max(move, stay)

複雜度
#

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

要特別避免的錯誤
#

  • 往左移時,左邊那格如果已經被蓋住,不能重複加分。
  • 第 0 格的代幣不能往左移,move 初始化成負無限大。

面試口說整理
#

每個代幣只能往左移一格,所以從左到右做狀態機 DP,狀態是這格的代幣有沒有往左移。留在原地就加這格的值;往左移就加左邊那格的值,但如果左邊那格也有代幣,只有它自己往左移走了,這格才是空的,所以只能從 move 狀態轉移。時間 O(n)。

相關文章

LeetCode 122: Best Time To Buy And Sell Stock II
·2 分鐘
LeetCode Medium Dynamic-Programming Greedy State-Machine
LeetCode 122 解題筆記,依照原始 learning note 重新整理
LeetCode 3800: Minimum Cost to Make Two Binary Strings Equal
·1 分鐘
LeetCode Medium Greedy String
LeetCode 3800 解題筆記:不相等的位置分兩類;不同類的兩兩用 swap,同類的兩兩用 cross + swap,剩一個只能 flip,每種都跟兩次 flip 比
LeetCode 1616: Split Two Strings to Make Palindrome
·2 分鐘
LeetCode Medium Two-Pointers String Greedy
LeetCode 1616 解題筆記:外側用 a 的前綴配 b 的後綴貪心比對,配不下去時,剩下的中間段必須整段在 a 或 b 裡是回文;兩個方向都要檢查
LeetCode 1888: Minimum Number of Flips to Make the Binary String Alternating
·1 分鐘
LeetCode Medium Sliding-Window String Dynamic-Programming
LeetCode 1888 解題筆記:把移到尾巴的操作變成在 s + s 上滑動長度 n 的視窗;視窗跟 0101… 不同的數量是 diff,跟 1010… 不同的就是 n - diff
LeetCode 2745: Construct the Longest New String
·1 分鐘
LeetCode Medium Dynamic-Programming Math Greedy Brainteaser
LeetCode 2745 解題筆記:AA 和 BB 必須交替出現,最多用 min(x, y) 對,多的那種還能再多放一個;AB 全部都能接上
LeetCode 376: Wiggle Subsequence
·3 分鐘
LeetCode Medium Dynamic-Programming Greedy
LeetCode 376 解題筆記,依照原始 learning note 重新整理