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_products and min_products to 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_products array

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.

Updated on: 2026-03-25T07:59:11+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements