LeetCode – Maximum Product Subarray (Java)

Find the contiguous subarray within an array (containing at least one number) which has the largest product.

For example, given the array [2,3,-2,4], the contiguous subarray [2,3] has the largest product = 6.

Java Solution - Dynamic Programming

This is similar to maximum subarray. Instead of sum, the sign of number affect the product value.

When iterating the array, each element has two possibilities: positive number or negative number. We need to track a minimum value, so that when a negative number is given, it can also find the maximum value. We define two local variables, one tracks the maximum and the other tracks the minimum.

public int maxProduct(int[] nums) {
    int[] max = new int[nums.length];
    int[] min = new int[nums.length];
 
    max[0] = min[0] = nums[0];
    int result = nums[0];
 
    for(int i=1; i<nums.length; i++){
        if(nums[i]>0){
            max[i]=Math.max(nums[i], max[i-1]*nums[i]);
            min[i]=Math.min(nums[i], min[i-1]*nums[i]);
        }else{
            max[i]=Math.max(nums[i], min[i-1]*nums[i]);
            min[i]=Math.min(nums[i], max[i-1]*nums[i]);
        }
 
        result = Math.max(result, max[i]);
    }
 
    return result;
}

Time is O(n).

Category >> Algorithms >> Interview  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • alexwest11

    obv exist better solution

    1) if zeroes are allowed, we need to find out max product between zeroes in all sub arrays

    2) if sub array have all positives, thus product is all elements

    3) if sub array have even number of negs, thus product is all elements

    4) last case: number of negs is odd: max products is product of all elements after 1st neg, or before last neg..

    xxx neg1 xxxxxx neg-last xxxx

  • Alik Elzin

    In the given solution, why are `min` and `max` arrays?

  • Nilesh Rokade

    public static void MaxProductinSubarray()
    {
    int[] a = { 3, 2, -1, 4 };//{ 3, 4, -3, 2, 1, 9 };//{0 ,-2, -3, 0, -2, -40 };//{ 6, -3, -10, 0, 2 };//{ -1, -3, -10, 0, 60 };//
    int maxProduct = 0, currentMax = 0;
    foreach (var item in a)
    {

    if (currentMax == 0 || item == 0)
    currentMax = item;

    else
    currentMax = currentMax * item;

    if (currentMax > maxProduct)
    maxProduct = currentMax;

    if ( currentMax 0)
    {
    currentMax = 1;
    }

    }
    Console.WriteLine(maxProduct);
    }

  • ryanlr

    The provided solution does not handle negative case, try this input: [-5, 2, -5]

  • Satish

    public static int maxSubProductArray(int[] nums) {
    if (nums.length == 0) {
    return 0;
    }
    int result = nums[0], prod = nums[0], prevProd = nums[0];
    for (int i = 1; i < nums.length; i++) {
    prod *= nums[i];
    if (prod < prevProd) {
    prod = nums[i];
    }
    result = Math.max(result, prod);
    prevProd = prod;
    }
    return result;
    }

  • Shailesh Hegde

    This is even more better i guess:

    public int maximumProductSubArray(int a[])
    {
    int max = Integer.MIN_VALUE;

    for(int i=0;i<nums.length;i++)
    {
    int product =1;
    for(int j=i;j<nums.length;j++)
    {
    product = product * nums[j];
    max = Math.max(max,product);
    }
    return max;
    }
    }

  • Marina

    Fixed solution from comments. Passes leet code test:
    int min_so_far = nums[0];
    int max_so_far = nums[0];
    int curr_max = nums[0];
    int curr_min = nums[0];
    int result = nums[0];
    for (int i = 1; i 0) {
    curr_max = Math.max(nums[i],nums[i] * max_so_far);
    curr_min = Math.min(nums[i] , nums[i] * min_so_far);

    } else {
    curr_max = Math.max(nums[i],nums[i] * min_so_far);
    curr_min = Math.min(nums[i] , nums[i] * max_so_far);
    }
    max_so_far = curr_max;
    min_so_far = curr_min;
    result = Math.max(result,max_so_far);
    }
    return result;

  • Dev Khimasia

    [-2,1,-1] gives the result 2 which is incorrect.
    It should be 1
    Am I missing something here?

  • Jayaraman Shanmugam

    I am not sure this is correct. Can someone confirm if this has any flaws ? I am getting result as 18.

    public static void main(String[] args) {

    int[] numArray={2,-7,2,9};

    int largestProduct=numArray[0];
    int product=numArray[0];

    for (int i=1;i<numArray.length;i++){
    product = Math.max(numArray[i], product*numArray[i]);
    largestProduct=Math.max(largestProduct, product);
    }

    System.out.println(largestProduct);
    }

  • Archit

    Constant space using dynamic programming !


    public int maxProductConstantSpace(int[] nums){
    int min_so_far = nums[0];
    int max_so_far = nums[0];
    int curr_max = nums[0];
    int curr_min = nums[0];
    int result = 0;
    for (int i = 1; i 0){
    curr_max = Math.max(nums[i],nums[i] * max_so_far);
    curr_min = Math.min(nums[i] , nums[i] * min_so_far);

    } else {
    curr_max = Math.max(nums[i],nums[i] * min_so_far);
    curr_min = Math.min(nums[i] , nums[i] * max_so_far);
    }
    max_so_far = curr_max;
    min_so_far = curr_min;
    result = Math.max(result,max_so_far);
    }
    return result;
    }

  • Milan


    public int maxProduct(int[] nums) {
    if (nums.length < 1)
    return 0;
    int max = nums[0];
    int currentMax = max;
    int min = max;
    for (int i =1;i<nums.length;i++){
    int temp = Math.min(nums[i], Math.min(min*nums[i],currentMax*nums[i]));
    currentMax = Math.max(nums[i], Math.max(min*nums[i],currentMax*nums[i]));
    min = temp;
    max = Math.max(max,currentMax);
    }
    return max;
    }

  • Shashi Kant

    works for zero element case too

    public static int maximumProductSubArray(int[] arr){

    int maxProd=1;

    for(int start=0;start 0; end–) {

    int prod=1;

    for(int i=start;i<=end;i++){

    prod*=arr[i];

    }

    maxProd=Math.max(maxProd, prod);

    }

    }

    return maxProd;

    }

  • jason zhang

    Brute force is not correct. For example, this test case can not pass: [-2, 4]

    Another solution. Should be faster than DP

    //if we have zero, we reset maxXXXWithLastElement

    //assume that no element is zero.

    public static int maximumSubarrayProduct(int[] input){

    //remove simple case to simplify process

    if (input.length==1){

    return input[0];

    }

    int allProduct=1;

    for (int i=0; i0){

    return allProduct;

    }

    //all value is negative

    int left=0;

    int right=input.length-1;

    //find the right most index which gives us an positive number.

    for (; right>=0; right–){

    allProduct=allProduct/input[right];

    if(allProduct>0){

    max=Math.max(allProduct, max);

    right–;

    break;

    }

    }

    if (right==-1){

    //we can not have a positive number if subarray starting from zero.

    //only one element is included;

    allProduct=input[0];

    max=allProduct;

    right=0;

    }

    //the max value is input[0]*input[1]*…*input[right];

    int leftOver=allProduct;

    int newLeft=left;

    for (; newLeft0 && allProduct<0) || (leftOver0)){

    //switch signed;

    newLeft++;

    break;

    }

    }

    int newAllValue=leftOver;

    for (int j=right+1; j<input.length; j++){

    newAllValue*=input[j];

    }

    max=Math.max(newAllValue, max);

    return max;

    }