Given an integer array nums, return the largest product achievable by any contiguous subarray.
Example
Input nums = [2,3,-2,4]
Output 6
Key Pointers
Unlike max subarray sum, a negative number can flip the smallest (most negative) running product into the largest — so both a running max and a running min must be tracked.
At each step, the new max/min candidates are the current number alone, current × previous max, or current × previous min — because a negative current number swaps which of the previous max/min becomes useful.
A zero effectively resets both running products, and the "current number alone" candidate naturally handles that without special-casing it.
Step-by-Step Analysis
Initialize result, cur_max, and cur_min all to nums[0].
For each following number n, compute the three candidates: n itself, n × cur_max, and n × cur_min.
Set cur_max to the largest of the three candidates and cur_min to the smallest.
Update result to the larger of itself and cur_max; return result once the array is exhausted.
Complexity
Time: O(n) — Space: O(1)
Code
def maxProduct(nums: list[int]) -> int:
result = nums[0]
cur_max, cur_min = nums[0], nums[0]
for n in nums[1:]:
candidates = (n, n * cur_max, n * cur_min)
cur_max, cur_min = max(candidates), min(candidates)
result = max(result, cur_max)
return result
Code Explanation
How the solution above works, piece by piece.
For each position, track the largest and the smallest product of a subarray ending there.
The smallest matters because a negative number flips signs: a very negative product times a negative becomes very positive.
The new max/min come from three candidates: start fresh at n, extend the previous max, or extend the previous min.
result keeps the best max seen anywhere.
One pass, O(1) space.
Visual Walkthrough
Running it on nums = [2, 3, -2, 4]:
At −2 the best product so far (6) turns into −12 as the new minimum; it would become useful if another negative number came later. The answer is 2 × 3 = 6.