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>
  • 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;

    }