Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Maximum Product Subarray in Python
The Maximum Product Subarray problem asks us to find a contiguous subarray within an integer array that has the largest product. For example, in the array [2,3,-2,4], the subarray [2,3] gives the maximum product of 6.
This problem is tricky because negative numbers can turn a small product into a large one when multiplied by another negative number. We need to track both maximum and minimum products at each position.
Algorithm
We use dynamic programming to solve this problem ?
- Create two arrays:
max_productsandmin_productsto track maximum and minimum products ending at each position - Initialize both arrays' first elements with the first number
- For each subsequent element, calculate the maximum and minimum products by considering three possibilities:
- Current element alone
- Current element multiplied by previous maximum
- Current element multiplied by previous minimum
- Return the maximum value from the
max_productsarray
Implementation
def max_product_subarray(nums):
if not nums:
return 0
n = len(nums)
max_products = [0] * n
min_products = [0] * n
# Initialize first elements
max_products[0] = nums[0]
min_products[0] = nums[0]
for i in range(1, n):
# Calculate maximum product ending at position i
max_products[i] = max(
nums[i],
max_products[i-1] * nums[i],
min_products[i-1] * nums[i]
)
# Calculate minimum product ending at position i
min_products[i] = min(
nums[i],
max_products[i-1] * nums[i],
min_products[i-1] * nums[i]
)
return max(max_products)
# Test with example
numbers = [2, 3, -2, 4, -5, -6, 2]
result = max_product_subarray(numbers)
print(f"Maximum product subarray: {result}")
Maximum product subarray: 240
How It Works
Let's trace through the algorithm with [2, 3, -2, 4, -5, -6, 2] ?
def max_product_subarray_trace(nums):
n = len(nums)
max_products = [0] * n
min_products = [0] * n
max_products[0] = nums[0]
min_products[0] = nums[0]
print(f"Position 0: max={max_products[0]}, min={min_products[0]}")
for i in range(1, n):
candidates = [
nums[i],
max_products[i-1] * nums[i],
min_products[i-1] * nums[i]
]
max_products[i] = max(candidates)
min_products[i] = min(candidates)
print(f"Position {i}: candidates={candidates}, max={max_products[i]}, min={min_products[i]}")
return max(max_products)
# Trace the execution
numbers = [2, 3, -2, 4, -5, -6]
result = max_product_subarray_trace(numbers)
print(f"\nMaximum product: {result}")
Position 0: max=2, min=2 Position 1: candidates=[3, 6, 6], max=6, min=3 Position 2: candidates=[-2, -12, -6], max=-2, min=-12 Position 3: candidates=[4, -8, -48], max=4, min=-48 Position 4: candidates=[-5, 20, 240], max=240, min=-240 Position 5: candidates=[-6, -1440, 1440], max=1440, min=-1440 Maximum product: 1440
Space-Optimized Solution
We can optimize space complexity by using variables instead of arrays ?
def max_product_optimized(nums):
if not nums:
return 0
max_prod = min_prod = result = nums[0]
for i in range(1, len(nums)):
current = nums[i]
# Store previous max_prod before updating
temp_max = max_prod
max_prod = max(current, max_prod * current, min_prod * current)
min_prod = min(current, temp_max * current, min_prod * current)
result = max(result, max_prod)
return result
# Test both approaches
numbers = [2, 3, -2, 4]
print(f"Array: {numbers}")
print(f"Maximum product: {max_product_optimized(numbers)}")
Array: [2, 3, -2, 4] Maximum product: 6
Comparison
| Approach | Time Complexity | Space Complexity | Advantage |
|---|---|---|---|
| Array-based | O(n) | O(n) | Easy to understand and debug |
| Space-optimized | O(n) | O(1) | Memory efficient |
Conclusion
The Maximum Product Subarray problem requires tracking both maximum and minimum products due to negative numbers potentially creating larger products. The dynamic programming approach solves this in O(n) time, with an optional O(1) space optimization.
