Lessons
Arrays
Dynamic Programming
Graph
Hashing
Maximum Product Subarray
The Maximum Product Subarray problem challenges you to find the contiguous subarray within an array that has the highest possible product. Unlike the maximum subarray sum, the introduction of negative numbers, positive numbers, and zero significantly affects the result, making it more complex and interesting.
Solving this efficiently requires a careful optimization strategy combined with dynamic programming principles. Let's dive into the methods, ideas, and Python implementation.
Problem Statement
Given an integer array, find the contiguous subarray that produces the maximum product.
Example:
Input: [2,3,-2,4]
Output: 6
Explanation: The subarray [2,3]
has the product 6
, which is the maximum among all subarrays.
Because of the presence of negative numbers and zero, we must rethink how to design the solution beyond simple multiplication.
Why a Simple Approach Fails
If we simply multiply elements as we do in the sum version, encountering a zero or a negative number can reset or flip the result entirely.
Thus, a simple iteration without smart tracking would miss correct answers, especially when a later negative number could flip a minimum into a maximum.
Optimized Approach Using Dynamic Programming
The right optimization strategy involves maintaining both a local maximum and a local minimum at every step:
- A local maximum keeps track of the highest product ending at the current element.
- A local minimum keeps track of the lowest product ending at the current element, because multiplying two negative numbers could yield a new positive number.
During the iteration, each new element can:
- Increase the existing local maximum.
- Turn the local minimum into a new local maximum (when multiplying two negatives).
- Reset everything if the element is zero.
This clever tracking makes sure that no potential maximum is missed.
Step-by-Step Algorithm
- Initialize
local_max
,local_min
, andglobal_max
to the first element of the array. - For each element from the second position onward:
- If the element is negative, swap
local_max
andlocal_min
. - Update
local_max
as the maximum between the current element andlocal_max * current element
. - Update
local_min
similarly. - Update
global_max
iflocal_max
exceeds it.
- If the element is negative, swap
This method guarantees a complete dynamic programming solution with proper optimization.
Python Implementation
python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
def maxProduct(nums): if not nums: return 0 local_max = nums[0] local_min = nums[0] global_max = nums[0] for num in nums[1:]: if num < 0: local_max, local_min = local_min, local_max local_max = max(num, local_max * num) local_min = min(num, local_min * num) global_max = max(global_max, local_max) return global_max
This code performs a linear iteration over the array, ensuring O(n) time complexity and O(1) space complexity.
Handling Special Cases
- If the array contains a zero, the product must reset because anything multiplied by zero becomes zero.
- Multiple negative numbers can cancel each other out to produce a new positive number.
- A subarray containing a single element may still be the correct answer if it's the maximum.
Correct tracking during iteration ensures that all these cases are automatically handled.
Conclusion
The Maximum Product Subarray is a fascinating blend of careful array processing, smart subarray product tracking, and effective use of dynamic programming.
By maintaining a local maximum and local minimum and resetting around zero, we achieve perfect optimization for both time and space.
Mastering this pattern not only helps in solving similar problems involving negative numbers and positive numbers but also strengthens your skills in iteration-based algorithms.