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 = min = nums; int result = nums;   for(int i=1; i0){ 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>
• Alik Elzin

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

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, prod = nums, prevProd = nums;
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;
int max_so_far = nums;
int curr_max = nums;
int curr_min = nums;
int result = nums;
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;
int product=numArray;

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;
int max_so_far = nums;
int curr_max = nums;
int curr_min = nums;
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;
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;

}

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;

max=allProduct;

right=0;

}

//the max value is input*input*…*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;

}