Maximum Product Subarray

medium

You are given an integer array nums. Find the contiguous, non-empty subarray whose elements multiply together to give the largest product, and return that product.

A subarray of a single element counts — its product is simply that element. The tests are constructed so that the answer (and every subarray product along the way) fits in a 32-bit integer.

Hints

The running-best trick from maximum subarray sum almost works here. What property of multiplication breaks it that addition doesn't have?
A negative number reverses order: it turns the largest running product into the smallest — and the smallest into the largest. So a terrible running product might be one step from the answer.
At each index, track BOTH the maximum and the minimum product of a subarray ending there. When the next element is negative, swap them; each is then either the element alone or the previous runner times the element.

Common doubts

Because a negative element flips signs: curMin * x can exceed curMax * x when x < 0. On [-2, 3, -4] the running minimum -6 becomes the winning 24 — tracking only the maximum answers 3.
They reset it, and the update rule handles that automatically: at x = 0, max(x, curMax * x) and min(x, curMin * x) both become 0, so the scan restarts after the zero. best already remembered everything before it.
Yes. The subarray must be non-empty, so for nums = [-2] the answer is -2. That is why best is initialized to nums[0], never to 0 or 1.
Every subarray ending at x either extends the previous one or starts fresh at x. The x term is the restart option — dropping it forces every subarray to stretch back to index 0.

Interview follow-ups

Carry a start index alongside each runner: when a runner restarts at x, its start becomes the current index; when it extends, the start is inherited (and swapped when the runners swap). Record the (start, end) pair whenever best improves.
Avoid materializing the product: compare using sums of logarithms of absolute values, tracking the sign separately and treating zeros as segment breaks. Same O(n) scan, overflow-proof.
Yes — an elegant two-pass trick. The best subarray is always a prefix or a suffix of some zero-free segment, so scan left-to-right and right-to-left with a running product that resets to 1 after a zero, and take the maximum seen in either direction.

Fun facts

  • This is Kadane's algorithm with one twist: addition preserves order but multiplication by a negative reverses it, so the scan must carry the minimum runner alongside the maximum.
  • The max-and-min pairing generalizes: whenever a scan's operation can flip which candidate is best (products, sign changes, ratios), tracking both extremes ending at each index keeps the DP honest — the same idea powers variants like maximum absolute product and sign-of-product queries.

Asked at

AmazonMicrosoftGoogleAppleAdobe
Frequently Sometimes Occasionally
Example 1
Input: nums = [2,3,-2,4]
Output: 6
The subarray [2,3] has the largest product, 2 × 3 = 6.
Example 2
Input: nums = [-2,0,-1]
Output: 0
The answer cannot be 2 because [-2,-1] is not contiguous. The best we can do is the single element [0].
Constraints

- 1 <= nums.length <= 2 * 10^4 - -10 <= nums[i] <= 10 - The product of any subarray of nums is guaranteed to fit in a 32-bit integer.

Solve this problem →