↓Skip to main content
  1. LeetCode/

LeetCode 3952: Maximum Total Value of Covered Indices

·2 mins· ·
LeetCode Medium Dynamic-Programming State-Machine Greedy String
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2026-06-11

  • Submissions: Accepted (first try)

Approach
#

A token moves left at most one step, so the token at i only affects indices i - 1 and i. Run a state machine DP left to right on whether the token at i moved left:

  • stay: best after the first i indices with the token at i staying (or no token at i).
  • move: best after the first i indices with the token at i moved to i - 1.

Transitions at index i:

  • No token: both states are max(move, stay).
  • Token stays: max(move, stay) + nums[i].
  • Token moves left: index i - 1 becomes covered, but it may already have been:
    • If i - 1 also has a token, covering it helps only if that token moved away (the move state): move + nums[i - 1].
    • If i - 1 has no token, it was certainly uncovered: max(move, stay) + nums[i - 1].

All values are positive, so taking a value is never worse.

My Solution
#

class Solution:
    def maxTotal(self, nums: List[int], s: str) -> int:
        move = float("-inf")                       # the token at index 0 cannot move left
        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]  # only free if the left token moved away
                else:
                    new_move = best + nums[i - 1]
            else:
                new_stay = new_move = best
            move, stay = new_move, new_stay
        return max(move, stay)

Complexity
#

Time O(n), space O(1).

Mistakes to Avoid
#

  • When moving left, do not count the left index again if it is already covered.
  • The token at index 0 cannot move left, so move starts at negative infinity.

Interview Explanation
#

Each token moves left at most once, so I run a left-to-right state machine DP on whether this index’s token moved left. Staying adds this index’s value; moving adds the left index’s value, but if the left index has its own token, it is empty only if that token moved away, so the transition comes only from the move state. Time O(n).

Related

LeetCode 122: Best Time To Buy And Sell Stock II
·2 mins
LeetCode Medium Dynamic-Programming Greedy State-Machine
LeetCode note for Best Time To Buy And Sell Stock II, rebuilt from the original learning note
LeetCode 3800: Minimum Cost to Make Two Binary Strings Equal
·2 mins
LeetCode Medium Greedy String
LeetCode 3800 note: split mismatches into two kinds; pair different kinds with a swap, same kinds with cross + swap, flip any leftover, and compare each against two flips
LeetCode 1616: Split Two Strings to Make Palindrome
·3 mins
LeetCode Medium Two-Pointers String Greedy
LeetCode 1616 note: greedily match a’s prefix against b’s suffix from the outside in; the leftover middle must be a palindrome entirely within a or b, and both directions need checking
LeetCode 1888: Minimum Number of Flips to Make the Binary String Alternating
·2 mins
LeetCode Medium Sliding-Window String Dynamic-Programming
LeetCode 1888 note: rotations become length-n windows over s + s; the window’s mismatches against 0101… are diff, and against 1010… they are n - diff
LeetCode 2745: Construct the Longest New String
·2 mins
LeetCode Medium Dynamic-Programming Math Greedy Brainteaser
LeetCode 2745 note: AA and BB must alternate, using min(x, y) pairs plus one extra of the more common kind, and every AB fits in
LeetCode 2131: Longest Palindrome by Concatenating Two Letter Words
·2 mins
LeetCode Medium Greedy Hash-Table String Counting
LeetCode 2131 note: pair each word with its reverse on both sides; self-palindromes also pair with each other, and only one leftover can sit in the middle