◀ THE GRIND — 1-D DYNAMIC PROGRAMMING

Maximum Product Subarray

MEDIUM✓ CHIP-TIMEDLC #152 — FULL STATEMENT ↗

The drill: Somewhere in an array of integers, one contiguous run multiplies out to the largest product of any run. Find that maximum product.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

A list of integers arrives, and the task is to scan every contiguous stretch of it — never skipping around — and multiply the values inside that stretch together. Somewhere among all those possible stretches sits one whose product beats every other stretch's product.

Negative numbers are the whole trick here: a single negative flips the sign of everything it touches, so a very negative running product can vault to the top the moment one more negative value joins it. Zeros act as hard resets, since a zero anywhere kills the product of a run through it.

A run of exactly one number is a valid stretch on its own, so the answer always exists even when every value is negative or the whole array is one number. The output is just the largest product found, not the stretch itself.

EX 01
nums = [3]
3
MINIMUM SIZE, SINGLE POSITIVE
EX 02
nums = [-3]
-3
MINIMUM SIZE, SINGLE NEGATIVE
EX 03
nums = [2, 3, -2, 4]
6
A TRAILING NEGATIVE KILLS THE BEST RUN EARLY
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

A running max that only tracks the biggest product so far breaks the moment a negative number shows up — what can a negative number turn a small product into?

HINT 2 THE STRUCTURE

A negative number flips the sign of whatever it multiplies — so the smallest, most negative running product can become the largest the instant one more negative joins it. Track both extremes.

HINT 3 ONE STEP FROM THE ANSWER

At each element compute the new max and new min as the best and worst of (element alone, max·element, min·element) — a negative element is exactly what swaps their roles.

COACH'S BOARD — THE PATTERN, STEP BY STEP
TRACKING MAX AND MINPATTERN · TRACK MAX AND MINnums = [2, -5, -2, -4, 3]
2
-5
-2
-4
3
RUNNING PRODUCTS
— empty —
STEP 1

Negatives flip signs — a very negative running product can vault to the top when one more negative joins it. Track both max AND min.

STEP 1 / 7 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/maximum-product-subarray.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        best = cur_max = cur_min = nums[0]
        for x in nums[1:]:
            candidates = (x, cur_max * x, cur_min * x)
            cur_max, cur_min = max(candidates), min(candidates)
            best = max(best, cur_max)
        return best
TIME O(N)SPACE O(1)PYTHON · RACE PACE · 8 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED