08. Maximum Product Subarray
β GFG solution to the Maximum Product Subarray problem: find the maximum product of any subarray using dynamic programming technique. π
The problem can be found at the following link: π Question Link
π§© Problem Description
Given an array arr[] that contains positive and negative integers (may contain 0 as well). Find the maximum product that we can get in a subarray of arr[].
A subarray is a contiguous sequence of elements within an array. The goal is to find the maximum possible product of elements in any such subarray.
Note: It is guaranteed that the answer fits in a 32-bit integer.
π Examples
Example 1
Input: arr[] = [-2, 6, -3, -10, 0, 2]
Output: 180
Explanation: The subarray with maximum product is [6, -3, -10] with product = 6 * (-3) * (-10) = 180.Example 2
Input: arr[] = [-1, -3, -10, 0, 6]
Output: 30
Explanation: The subarray with maximum product is [-3, -10] with product = (-3) * (-10) = 30.Example 3
π Constraints
$1 \le \text{arr.size()} \le 10^6$
$-10 \le \text{arr}[i] \le 10$
β
My Approach
The optimal approach uses Dynamic Programming with Max-Min Tracking to efficiently handle both positive and negative numbers:
Max-Min Tracking (Modified Kadane's Algorithm)
Initialize Variables:
mx= maximum product ending at current position (initialized toarr[0])mn= minimum product ending at current position (initialized toarr[0])r= global maximum product result (initialized toarr[0])
Key Insight:
We need to track both maximum AND minimum products because:
A negative number can turn the minimum product into maximum
A negative number can turn the maximum product into minimum
Example: If
mn = -10and current element is-3, then-10 * -3 = 30becomes the new maximum
Iterate Through Array:
For each element
arr[i](starting from index 1):Calculate
a = mx * arr[i](product with previous max)Calculate
b = mn * arr[i](product with previous min)Update
mx = max(a, b, arr[i])(either extend previous products or start fresh)Update
mn = min(a, b, arr[i])(track minimum for future negative multiplications)Update global result:
r = max(r, mx)
Handle Edge Cases:
Zero elements: When we encounter 0, both max and min reset to 0, and starting fresh from next element handles it naturally
All negatives: The min-max tracking ensures correct handling
Mixed signs: The dual tracking captures all possibilities
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(n), where n is the size of the array. We traverse the array exactly once, performing constant-time operations at each step.
Expected Auxiliary Space Complexity: O(1), as we only use three variables (mx, mn, r) regardless of input size, requiring constant additional space.
π§βπ» Code (C)
π§βπ» Code (C++)
β‘ View Alternative Approaches with Code and Analysis
π 2οΈβ£ Two-Pass Traversal
π‘ Algorithm Steps:
Traverse array left to right maintaining cumulative product.
Reset product to zero when product becomes zero.
Traverse array right to left with the same logic.
Track maximum product found in both directions.
π Complexity Analysis:
Time: β±οΈ O(n) - Two linear passes through the array
Auxiliary Space: πΎ O(1) - Constant space complexity
β
Why This Approach?
Handles negative numbers naturally with bidirectional scan
Simpler logic than tracking min and max simultaneously
Auto-resets on encountering zeros
π 3οΈβ£ Prefix-Suffix Product
π‘ Algorithm Steps:
Calculate prefix product from left and suffix product from right simultaneously.
Reset prefix or suffix to 1 when encountering zero.
Track maximum value from both prefix and suffix at each step.
Return the maximum product found in single pass.
π Complexity Analysis:
Time: β±οΈ O(n) - Single pass with dual direction processing
Auxiliary Space: πΎ O(1) - Only tracking prefix and suffix
β
Why This Approach?
Single pass efficiency
Symmetric processing from both ends
Clean zero handling with reset mechanism
π 4οΈβ£ Modified Kadane's Algorithm with Swap
π‘ Algorithm Steps:
Maintain three variables: current max, current min, and global max.
For each element, calculate new max as max of current element, maxelement, minelement.
Calculate new min similarly to handle negative number transitions.
Update global maximum at each step.
π Complexity Analysis:
Time: β±οΈ O(n) - Single pass with swap on negatives
Auxiliary Space: πΎ O(1) - Three variables for tracking
β
Why This Approach?
Extension of classic Kadane's algorithm
Explicit swap logic for negative numbers
Clear state transitions
π 5οΈβ£ Division-Based Approach
π‘ Algorithm Steps:
Calculate product of all non-zero elements.
Split array by zeros into segments.
For segments with odd negative count, try excluding first or last negative.
Return maximum product across all valid segments.
π Complexity Analysis:
Time: β±οΈ O(n) - Two passes for forward and backward
Auxiliary Space: πΎ O(1) - Constant space usage
β
Why This Approach?
Handles zeros and negatives effectively
Double pass ensures optimal subarray selection
Good for arrays with multiple zero partitions
π π Comparison of Approaches
π Approach
β±οΈ Time Complexity
πΎ Space Complexity
β Pros
β οΈ Cons
π·οΈ Max-Min Tracking
π’ O(n)
π’ O(1)
π Optimal single pass
π§ Tracks both max and min
π Two-Pass Traversal
π’ O(n)
π’ O(1)
π― Intuitive bidirectional
π Requires two complete passes
π Prefix-Suffix
π’ O(n)
π’ O(1)
β Single pass efficiency
π§ Simultaneous tracking needed
π¨ Modified Kadane's
π’ O(n)
π’ O(1)
π Classic algorithm pattern
π Explicit swap on negatives
β Division-Based
π’ O(n)
π’ O(1)
π― Handles zeros naturally
π§ More complex logic flow
π Best Choice Recommendation
π― Scenario
ποΈ Recommended Approach
π₯ Performance Rating
π Optimal performance needed
π₯ Max-Min Tracking
β β β β β
π Readability priority
π₯ Two-Pass Traversal
β β β β β
π― Interview/Competitive
π₯ Prefix-Suffix
β β β β β
π Algorithm pattern practice
ποΈ Modified Kadane's
β β β β β
π’ Many zeros in array
π Division-Based
β β β β β
β Code (Java)
π Code (Python)
π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated