Maximum Product Subarray

Updated on 12 June, 2025
Maximum Product Subarray header image

Problem Statement

The problem at hand is to identify a subarray from a given array of integers nums that delivers the maximum possible product of its elements. A subarray refers to a contiguous portion of the array. The output should be the largest product achievable from any such subarray. The challenge arises notably when the array contains both positive and negative numbers, since multiplying negative numbers can change the product dynamics significantly. It's also noteworthy that the solution must be computationally efficient given the potential size of the array and the range of integer values.

Examples

Example 1

Input:

nums = [2,3,-2,4]

Output:

6

Explanation:

[2,3] has the largest product 6.

Example 2

Input:

nums = [-2,0,-1]

Output:

0

Explanation:

The result cannot be 2, because [-2,-1] is not a subarray.

Constraints

  • 1 <= nums.length <= 2 * 104
  • -10 <= nums[i] <= 10
  • The product of any subarray of nums is guaranteed to fit in a 32-bit integer.

Approach and Intuition

To tackle this problem, understanding how the product of numbers behaves with the addition of new numbers, particularly with the presence of negative and zero values, is critical. Here's the step-by-step intuition and strategy to approach this problem:

  1. Initial Thoughts:

    • A straightforward brute-force approach would involve calculating the product of every possible subarray. However, this is inefficient as the number of subarrays of an array of length n is n(n+1)/2.
    • Key observation is the effect of negative numbers on the product. Two negatives make a positive, and a zero resets the subarray product to zero.
  2. Optimize with Dynamic Programming:

    • At each position in the array, consider two values:
      • The maximum product up to that position considering all subarrays ending at that position.
      • The minimum product (which might seem counterintuitive, but is critical because a very small product, when multiplied by a negative number, could turn into a very large product).
    • Update rules are:
      • Current maximum is the maximum of:
        • Product of the current element,
        • Product of the current element and the maximum product up to the previous position,
        • Product of the current element and the minimum product up to the previous position.
      • Similarly, update the current minimum.
  3. Behavior near zero:

    • A zero in the array will reset the cumulative product calculations. Hence, every time a zero is encountered, both the maximum and minimum products are reset to zero.
  4. Handling Edge Cases:

    • Single element arrays
    • Arrays containing all non-positive numbers
    • Arrays containing zero

By leveraging dynamic programming, we maintain the state of the maximum and minimum products at each step, adjusting our approach based on not only the current value but also the computations from previous steps. This ensures that we get an optimal solution without recalculating the products for overlapping subarrays repeatedly. This, aligned with the constraints of the problem, provides an efficient solution to extract the maximum product subarray efficiently.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int maximumProduct(vector<int>& nums) {
        if (nums.empty()) return 0;

        int highestProduct = nums[0];
        int lowestProduct = nums[0];
        int maxResult = highestProduct;

        for (int i = 1; i < nums.size(); i++) {
            int currentNum = nums[i];
            int tempHighest = max(currentNum, max(highestProduct * currentNum, lowestProduct * currentNum));
            lowestProduct = min(currentNum, min(highestProduct * currentNum, lowestProduct * currentNum));

            // Ensure that the highest product is based on the latest values
            highestProduct = tempHighest;
            // Keep track of the highest product achieved
            maxResult = max(highestProduct, maxResult);
        }

        return maxResult;
    }
};

The provided C++ code defines a solution to find the maximum product of a subarray within an array of integers. This approach is efficient and handles the complexity of both positive and negative numbers through some clever use of dynamic programming. Follow these steps to understand how the code operates:

  1. Declare and initialize variables highestProduct and lowestProduct to the first element of the array, ensuring a starting point for comparison. Also, initialize maxResult to store the global maximum product.

  2. Iterate through the array starting from the second element. For each element:

    • Calculate the temporary highest product using the current number. This involves comparing the product of the current number with the highest and lowest products from previous iterations. This captures potential transitions where the maximum product might be formed from the product of the lowest negative product (for negative numbers) and the current number.

    • Similarly, update lowestProduct to account for the potentially new lowest product using similar logic. This ensures tracking of lowest products, which is crucial when dealing with negative numbers as the product of two negatives becomes positive.

    • Update highestProduct with the temporary maximum value computed.

    • Continually update maxResult, ensuring at each step that the maximum product calculated so far is recorded.

  3. After the loop, maxResult will contain the maximum product of any subarray within the array.

This method handles the edge case of an empty array by returning 0 directly, which safeguards against invalid operations. The approach uses a linear scan with a constant space complexity, optimal for cases where a quick solution is required without modifying the original array.

java
public class Solution {

    public int maximumProduct(int[] array) {
        if (array.length == 0) return 0;

        int highestProduct = array[0];
        int lowestProduct = array[0];
        int maxResult = highestProduct;

        for (int index = 1; index < array.length; index++) {
            int currentElement = array[index];
            int temporaryMax = Math.max(
                currentElement,
                Math.max(highestProduct * currentElement, lowestProduct * currentElement)
            );
            lowestProduct = Math.min(
                currentElement,
                Math.min(highestProduct * currentElement, lowestProduct * currentElement)
            );

            highestProduct = temporaryMax;
            maxResult = Math.max(highestProduct, maxResult);
        }

        return maxResult;
    }
}

The provided code in Java aims to find the maximum product of a subarray from a given integer array. Here's a concise summary of the solution approach:

  • Begin by checking if the input array is empty. If yes, return 0.
  • Initialize three variables:
    • highestProduct to store the maximum product including the current number.
    • lowestProduct to store the minimum product including the current number (important for handling negative numbers).
    • maxResult to keep track of the highest product found so far, initialized to the first element of the array.
  • Iterate through the array starting from the second element.
  • For each element:
    • Calculate a temporary maximum which is the highest value among:
      • The current element itself (handles the case where starting a new subarray with the current element is more beneficial).
      • The product of the current element and highestProduct (continuation of the existing subarray).
      • The product of the current element and lowestProduct (important when the current element is negative which could turn a negative product into a positive).
    • Update lowestProduct by choosing the minimum among:
      • The current element.
      • The product of the current element and highestProduct.
      • The product of the current element and lowestProduct.
    • Update highestProduct to the value of temporaryMax.
    • Update maxResult to ensure it holds the maximum product found so far.
  • The final value of maxResult after processing all elements will be the maximum product of a subarray in the given array.

Return maxResult as it now contains the maximum product subarray value.

python
class Solution:
    def maximumProduct(self, numbers):
        if not numbers:
            return 0

        highest_product = numbers[0]
        lowest_product = numbers[0]
        max_product_result = highest_product

        for index in range(1, len(numbers)):
            number = numbers[index]
            temp_high = max(number, highest_product * number, lowest_product * number)
            lowest_product = min(number, highest_product * number, lowest_product * number)

            highest_product = temp_high
            max_product_result = max(highest_product, max_product_result)

        return max_product_result

The provided Python code defines a solution for finding the maximum product subarray from a list of integers. This can be very useful in contexts where you need to determine the largest product that can be obtained by multiplying consecutive elements in an array.

The class Solution includes a method maximumProduct which takes a list of integers numbers as input. Here's a breakdown of how the method works:

  • First, the method checks if the input list is empty. If it is, it returns 0, as no product can be computed from an empty list.

  • It initializes three variables: highest_product, lowest_product, and max_product_result. Initially, all these are set to the first element of the list. This is because the maximum or minimum product subarray might start with just the first element.

  • Next, the method iterates through the list starting from the second element. For each number in the list:

    • It calculates the temporary highest product considering the current number. This is determined by taking the maximum of three values: the current number itself, the product of the current number and the previous highest product, and the product of the current number and the previous lowest product.
    • Similarly, it updates the lowest_product which is the minimum of the same three values mentioned above. This step is crucial as multiplying two negative numbers yields a positive product, thus the lowest product might turn into the highest when a new number is considered.
    • The highest_product is then updated to the value of temp_high.
    • The max_product_result is updated to be the maximum value between the current highest_product and the existing max_product_result.
  • Once all elements have been processed, the method returns max_product_result, which contains the maximum product of any subarray within the input list.

This approach ensures that you efficiently find the maximum product subarray with a time complexity of O(n), where n is the number of elements in the input list, making it suitable for large datasets.

Comments

No comments yet.