↓Skip to main content
  1. LeetCode/

LeetCode 1354: Construct Target Array With Multiple Sums

·3 mins· ·
LeetCode Hard Heap Math Greedy
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: hard First Attempt: 2026-09-07

  • Submissions: Time Limit Exceeded → Accepted

Approach
#

Going forward has too many choices, so work backwards:

Each operation sets one position to the current total, which is larger than every other element. So the current maximum must be the position set most recently.

One step back: if the maximum is mx and the other elements sum to rest, that position previously held mx - rest.

Use a max-heap to repeatedly pop the maximum and undo one step. Succeed when everything is 1; fail if an undone value drops below 1.

My First Attempt: undoing one step at a time
#

preNum = preSum - (currSum - preSum)

For [1, 1000000000], each step subtracts only 1, so it takes 10^9 iterations and times out.

Improvement: jump with a modulo
#

When mx is much larger than rest, the same position is undone many times in a row, subtracting rest each time until it drops below rest. That is mx % rest.

Edge cases:

  • rest == 1: e.g. [1, x]; subtracting 1 repeatedly always reaches 1, so return True. Handle it first, because x % 1 == 0 would look like a failure.
  • rest == 0 (a single element that is not 1), or mx <= rest: no valid previous step, return False.
  • mx % rest == 0: the undone value would be 0, which is invalid, return False.

Solution
#

import heapq

class Solution:
    def isPossible(self, target: List[int]) -> bool:
        total = sum(target)
        heap = [-x for x in target]
        heapq.heapify(heap)

        while True:
            mx = -heapq.heappop(heap)
            if mx == 1:
                return True                    # the maximum is 1, so all are 1
            rest = total - mx
            if rest == 1:
                return True
            if rest == 0 or mx <= rest:
                return False
            prev = mx % rest
            if prev == 0:
                return False
            total = rest + prev
            heapq.heappush(heap, -prev)

Complexity
#

Time O(n + log(S) · log n), where S is the total: the maximum is at least half the total, and the modulo leaves less than half of it, so each round shrinks the total to at most 3/4. The loop runs only O(log S) times. Space O(n).

Mistakes to Avoid
#

  • Undoing one step at a time: times out when the gap is large.
  • Not handling rest == 1 first: x % 1 == 0 is mistaken for a failure.
  • Single-element arrays: rest == 0, and only [1] is True.

Interview Explanation
#

I work backwards: every set value is the total at that moment, so the current maximum was set last, and its previous value is the maximum minus the sum of the others. A max-heap gives the maximum each step; when the gap is large, the same position would be undone repeatedly, so a modulo does it in one jump. If the rest sums to 1 it always works; if it is 0 or not smaller than the maximum, or the modulo gives 0, it fails. Reaching all ones means success.

Related

LeetCode 499: The Maze III
·3 mins
LeetCode Hard Graph Dijkstra Shortest-Path Heap Matrix
LeetCode 499 note: Dijkstra prioritized by (distance, path string), and the ball stops when it rolls over the hole
LeetCode 1627: Graph Connectivity With Threshold
·2 mins
LeetCode Hard Math Number-Theory Union-Find Array
LeetCode 1627 note: no pairwise GCDs; for each z > threshold, connect all multiples of z, O(n log n) unions in total
LeetCode 2193: Minimum Number of Moves to Make Palindrome
·3 mins
LeetCode Hard Two-Pointers Greedy String Binary-Indexed-Tree
LeetCode 2193 note: greedily fix the outer pair: take the last character and swap its leftmost partner to the front, costing that index; the unpaired character ends in the middle, costing its distance there
LeetCode 420: Strong Password Checker
·4 mins
LeetCode Hard Greedy String
LeetCode 420 note: three length cases; when too long, delete from runs with len % 3 == 0 first to cancel replacements
LeetCode 2912: Number of Ways to Reach Destination in the Grid
·3 mins
LeetCode Hard Dynamic-Programming State-Machine Math Combinatorics
LeetCode 2912 note: many cells, but only four classes relative to the destination (itself, same row, same column, neither); each class’s total moves together in O(k)
LeetCode 60: Permutation Sequence
·2 mins
LeetCode Hard Math Combinatorics Recursion
LeetCode 60 note: make k 0-indexed; once the first digit is fixed there are (n-1)! arrangements, so k // (n-1)! picks the first digit among those remaining, then repeat for the next position