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).

13 thoughts on “LeetCode – Maximum Product Subarray (Java)”

  1. 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

  2. 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);
    }

  3. 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;
    }

  4. 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;
    }
    }

  5. 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;

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

  7. 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);
    }

  8. 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;
    }


  9. 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;
    }

  10. 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;

    }

  11. 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;

    }

Leave a Comment