# Maximum Product Subarray | Added negative product case

Given an array that contains both positive and negative integers, find the product of the maximum product subarray. Expected Time complexity is O(n) and only O(1) extra space can be used. The maximum product can be positive, negative or zero.

Examples:

```Input : arr[] = {-2, -3, 0, -2, -40}
Output : 80
Subarray : arr[3..4] i.e.{-2, -40}

Input : arr[] = {0, -4, 0, -2}
Output : 0
```

We have discussed this problem in Maximum Product Subarray, but there is a restriction that result can only be positive. For the maximum product to be negative or zero, the values of variable maxval (maximum product up to current element) and minval (minimum product up to current element), has to be updated as follows:

1. When arr[i] is positive : As maxval is maximum possible value, simply multiply arr[i] with maxval to obtain new maxval. minval is minimum possible negative product. If its previous value is negative then simply multiply it with arr[i]. If its value is 1 keep it as 1.
2. When arr[i] is 0 : Consider the test case : arr[] = {0, -4, 0, -2}. The maximum product is 0 in this case. To account for this case in our algo, update maxval with 0 instead of 1 whenever arr[i] is zero. The product of any number with zero is zero. Consider another test case, arr[] = {0, 1 ,2}.
If maxval remains zero after current iteration (according to the step described above) and the next element is positive then the result will be zero and not the positive element. To consider that at the end of each iteration check if maxval is zero or not.
If it is zero set it equal to 1. Update minval with 1 as subarray product with zero as element in it will be zero, which results in loss of minimum possible value. So exclude this zero from subarray by setting minval to 1, i.e., restarting product calculation.
3. When arr[i] is negative : new value of maxval is previous minval*arr[i] and new value of minval is previous maxval*arr[i]. Before updating maxval, store its previous value in prevMax to be used to update minval.

Implementation:

## C++

 `// C++ program to find maximum subarray product. ` `#include ` ` `  `using` `namespace` `std; ` ` `  `// Function to find maximum subarray product. ` `int` `findMaxProduct(``int` `arr[], ``int` `n) ` `{ ` `    ``int` `i; ` ` `  `    ``// As maximum product can be negative, so ` `    ``// initialize ans with minimum integer value. ` `    ``int` `ans = INT_MIN; ` ` `  `    ``// Variable to store maximum product until ` `    ``// current value. ` `    ``int` `maxval = 1; ` ` `  `    ``// Variable to store minimum product until ` `    ``// current value. ` `    ``int` `minval = 1; ` ` `  `    ``// Variable used during updation of maximum ` `    ``// product and minimum product. ` `    ``int` `prevMax; ` ` `  `    ``for` `(i = 0; i < n; i++) { ` ` `  `        ``// If current element is positive, update ` `        ``// maxval. Update minval if it is ` `        ``// negative. ` `        ``if` `(arr[i] > 0) { ` `            ``maxval = maxval * arr[i]; ` `            ``minval = min(1, minval * arr[i]); ` `        ``} ` ` `  `        ``// If current element is zero, maximum ` `        ``// product cannot end at current element. ` `        ``// Update minval with 1 and maxval with 0. ` `        ``// maxval is updated to 0 as in case all ` `        ``// other elements are negative, then maxval ` `        ``// is 0. ` `        ``else` `if` `(arr[i] == 0) { ` `            ``minval = 1; ` `            ``maxval = 0; ` `        ``} ` ` `  `        ``// If current element is negative, then new ` `        ``// value of maxval is previous minval*arr[i] ` `        ``// and new value of minval is previous ` `        ``// maxval*arr[i]. Before updating maxval, ` `        ``// store its previous value in prevMax to ` `        ``// be used to update minval. ` `        ``else` `if` `(arr[i] < 0) { ` `            ``prevMax = maxval; ` `            ``maxval = minval * arr[i]; ` `            ``minval = prevMax * arr[i]; ` `        ``} ` ` `  `        ``// Update ans if necessary. ` `        ``ans = max(ans, maxval); ` ` `  `        ``// If maxval is zero, then to calculate ` `        ``// product for next iteration, it should ` `        ``// be set to 1 as maximum product ` `        ``// subarray does not include 0. ` `        ``// The minimum possible value ` `        ``// to be considered in maximum product ` `        ``// subarray is already stored in minval, ` `        ``// so when maxval is negative it is set to 1. ` `        ``if` `(maxval <= 0) { ` `            ``maxval = 1; ` `        ``} ` `    ``} ` ` `  `    ``return` `ans; ` `} ` ` `  `int` `main() ` `{ ` `    ``int` `arr[] = { 0, -4, 0, -2 }; ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]); ` `    ``cout << findMaxProduct(arr, n); ` `    ``return` `0; ` `} `

## Java

 `     `  `// Java program to find maximum subarray product. ` ` ``class` `GFG{ ` `// Function to find maximum subarray product. ` `static` `int` `findMaxProduct(``int` `arr[], ``int` `n) ` `{ ` `    ``int` `i; ` `  `  `    ``// As maximum product can be negative, so ` `    ``// initialize ans with minimum integer value. ` `    ``int` `ans = Integer.MIN_VALUE; ` `  `  `    ``// Variable to store maximum product until ` `    ``// current value. ` `    ``int` `maxval = ``1``; ` `  `  `    ``// Variable to store minimum product until ` `    ``// current value. ` `    ``int` `minval = ``1``; ` `  `  `    ``// Variable used during updation of maximum ` `    ``// product and minimum product. ` `    ``int` `prevMax; ` `  `  `    ``for` `(i = ``0``; i < n; i++) { ` `  `  `        ``// If current element is positive, update ` `        ``// maxval. Update minval if it is ` `        ``// negative. ` `        ``if` `(arr[i] > ``0``) { ` `            ``maxval = maxval * arr[i]; ` `            ``minval = Math.min(``1``, minval * arr[i]); ` `        ``} ` `  `  `        ``// If current element is zero, maximum ` `        ``// product cannot end at current element. ` `        ``// Update minval with 1 and maxval with 0. ` `        ``// maxval is updated to 0 as in case all ` `        ``// other elements are negative, then maxval ` `        ``// is 0. ` `        ``else` `if` `(arr[i] == ``0``) { ` `            ``minval = ``1``; ` `            ``maxval = ``0``; ` `        ``} ` `  `  `        ``// If current element is negative, then new ` `        ``// value of maxval is previous minval*arr[i] ` `        ``// and new value of minval is previous ` `        ``// maxval*arr[i]. Before updating maxval, ` `        ``// store its previous value in prevMax to ` `        ``// be used to update minval. ` `        ``else` `if` `(arr[i] < ``0``) { ` `            ``prevMax = maxval; ` `            ``maxval = minval * arr[i]; ` `            ``minval = prevMax * arr[i]; ` `        ``} ` `  `  `        ``// Update ans if necessary. ` `        ``ans = Math.max(ans, maxval); ` `  `  `        ``// If maxval is zero, then to calculate ` `        ``// product for next iteration, it should ` `        ``// be set to 1 as maximum product ` `        ``// subarray does not include 0. ` `        ``// The minimum possible value ` `        ``// to be considered in maximum product ` `        ``// subarray is already stored in minval, ` `        ``// so when maxval is negative it is set to 1. ` `        ``if` `(maxval <= ``0``) { ` `            ``maxval = ``1``; ` `        ``} ` `    ``} ` `  `  `    ``return` `ans; ` `} ` `  `  `     ``public` `static` `void` `main(String[] args) { ` `          `  ` `  `    ``int` `arr[] = { ``0``, -``4``, ``0``, -``2` `}; ` `    ``int` `n = arr.length; ` `         ``System.out.println(findMaxProduct(arr, n)); ` `     ``} ` `} `

## Python3

 `# Python3 program to find maximum  ` `# subarray product.  ` ` `  `# Function to find maximum  ` `# subarray product.  ` `def` `findMaxProduct(arr, n):  ` ` `  `    ``# As maximum product can be negative, ` `    ``# so initialize ans with minimum  ` `    ``# integer value.  ` `    ``ans ``=` `-``float``(``'inf'``)  ` ` `  `    ``# Variable to store maximum product ` `    ``# until current value.  ` `    ``maxval ``=` `1` ` `  `    ``# Variable to store minimum product  ` `    ``# until current value.  ` `    ``minval ``=` `1` ` `  `    ``for` `i ``in` `range``(``0``, n):  ` ` `  `        ``# If current element is positive,  ` `        ``# update maxval. Update minval  ` `        ``# if it is negative.  ` `        ``if` `arr[i] > ``0``:  ` `            ``maxval ``=` `maxval ``*` `arr[i]  ` `            ``minval ``=` `min``(``1``, minval ``*` `arr[i])  ` `         `  `        ``# If current element is zero, maximum  ` `        ``# product cannot end at current element.  ` `        ``# Update minval with 1 and maxval with 0.  ` `        ``# maxval is updated to 0 as in case all  ` `        ``# other elements are negative, then  ` `        ``# maxval is 0.  ` `        ``elif` `arr[i] ``=``=` `0``:  ` `            ``minval ``=` `1` `            ``maxval ``=` `0` ` `  `        ``# If current element is negative,  ` `        ``# then new value of maxval is previous  ` `        ``# minval*arr[i] and new value of minval  ` `        ``# is previous maxval*arr[i]. Before  ` `        ``# updating maxval, store its previous  ` `        ``# value in prevMax to be used to  ` `        ``# update minval.  ` `        ``elif` `arr[i] < ``0``:  ` `            ``prevMax ``=` `maxval  ` `            ``maxval ``=` `minval ``*` `arr[i]  ` `            ``minval ``=` `prevMax ``*` `arr[i]  ` ` `  `        ``# Update ans if necessary.  ` `        ``ans ``=` `max``(ans, maxval)  ` ` `  `        ``# If maxval is zero, then to calculate  ` `        ``# product for next iteration, it should  ` `        ``# be set to 1 as maximum product subarray  ` `        ``# does not include 0. The minimum possible  ` `        ``# value to be considered in maximum product  ` `        ``# subarray is already stored in minval,  ` `        ``# so when maxval is negative it is set to 1.  ` `        ``if` `maxval <``=` `0``:  ` `            ``maxval ``=` `1` ` `  `    ``return` `ans  ` ` `  `# Driver Code ` `if` `__name__ ``=``=` `"__main__"``: ` ` `  `    ``arr ``=` `[ ``0``, ``-``4``, ``0``, ``-``2` `]  ` `    ``n ``=` `len``(arr)  ` `    ``print``(findMaxProduct(arr, n))  ` `     `  `# This code is contributed  ` `# by Rituraj Jain `

## C#

 `// C# program to find maximum subarray product. ` `using` `System; ` ` `  `class` `GFG ` `{ ` `// Function to find maximum subarray product. ` `static` `int` `findMaxProduct(``int``[] arr, ``int` `n) ` `{ ` `    ``int` `i; ` ` `  `    ``// As maximum product can be negative, so ` `    ``// initialize ans with minimum integer value. ` `    ``int` `ans = Int32.MinValue; ` ` `  `    ``// Variable to store maximum product until ` `    ``// current value. ` `    ``int` `maxval = 1; ` ` `  `    ``// Variable to store minimum product until ` `    ``// current value. ` `    ``int` `minval = 1; ` ` `  `    ``// Variable used during updation of maximum ` `    ``// product and minimum product. ` `    ``int` `prevMax; ` ` `  `    ``for` `(i = 0; i < n; i++) ` `    ``{ ` ` `  `        ``// If current element is positive, update ` `        ``// maxval. Update minval if it is ` `        ``// negative. ` `        ``if` `(arr[i] > 0)  ` `        ``{ ` `            ``maxval = maxval * arr[i]; ` `            ``minval = Math.Min(1, minval * arr[i]); ` `        ``} ` ` `  `        ``// If current element is zero, maximum ` `        ``// product cannot end at current element. ` `        ``// Update minval with 1 and maxval with 0. ` `        ``// maxval is updated to 0 as in case all ` `        ``// other elements are negative, then maxval ` `        ``// is 0. ` `        ``else` `if` `(arr[i] == 0)  ` `        ``{ ` `            ``minval = 1; ` `            ``maxval = 0; ` `        ``} ` ` `  `        ``// If current element is negative, then new ` `        ``// value of maxval is previous minval*arr[i] ` `        ``// and new value of minval is previous ` `        ``// maxval*arr[i]. Before updating maxval, ` `        ``// store its previous value in prevMax to ` `        ``// be used to update minval. ` `        ``else` `if` `(arr[i] < 0)  ` `        ``{ ` `            ``prevMax = maxval; ` `            ``maxval = minval * arr[i]; ` `            ``minval = prevMax * arr[i]; ` `        ``} ` ` `  `        ``// Update ans if necessary. ` `        ``ans = Math.Max(ans, maxval); ` ` `  `        ``// If maxval is zero, then to calculate ` `        ``// product for next iteration, it should ` `        ``// be set to 1 as maximum product ` `        ``// subarray does not include 0. ` `        ``// The minimum possible value ` `        ``// to be considered in maximum product ` `        ``// subarray is already stored in minval, ` `        ``// so when maxval is negative it is set to 1. ` `        ``if` `(maxval <= 0)  ` `        ``{ ` `            ``maxval = 1; ` `        ``} ` `    ``} ` ` `  `    ``return` `ans; ` `} ` ` `  `// Driver Code ` `public` `static` `void` `Main() ` `{ ` `    ``int``[] arr = { 0, -4, 0, -2 }; ` `    ``int` `n = arr.Length; ` `    ``Console.WriteLine(findMaxProduct(arr, n)); ` `} ` `} ` ` `  `// This code is contributed  ` `// by Akanksha Rai `

## PHP

 ` 0) ` `        ``{ ` `            ``\$maxval` `= ``\$maxval` `* ``\$arr``[i]; ` `            ``\$minval` `= min(1, ``\$minval` `* ``\$arr``[``\$i``]); ` `        ``} ` ` `  `        ``// If current element is zero, maximum ` `        ``// product cannot end at current element. ` `        ``// Update minval with 1 and maxval with 0. ` `        ``// maxval is updated to 0 as in case all ` `        ``// other elements are negative, then maxval ` `        ``// is 0. ` `        ``else` `if` `(``\$arr``[``\$i``] == 0)  ` `        ``{ ` `            ``\$minval` `= 1; ` `            ``\$maxval` `= 0; ` `        ``} ` ` `  `        ``// If current element is negative, then new ` `        ``// value of maxval is previous minval*arr[i] ` `        ``// and new value of minval is previous ` `        ``// maxval*arr[i]. Before updating maxval, ` `        ``// store its previous value in prevMax to ` `        ``// be used to update minval. ` `        ``else` `if` `(``\$arr``[``\$i``] < 0) ` `        ``{ ` `            ``\$prevMax` `= ``\$maxval``; ` `            ``\$maxval` `= ``\$minval` `* ``\$arr``[``\$i``]; ` `            ``\$minval` `= ``\$prevMax` `* ``\$arr``[``\$i``]; ` `        ``} ` ` `  `        ``// Update ans if necessary. ` `        ``\$ans` `= max(``\$ans``, ``\$maxval``); ` ` `  `        ``// If maxval is zero, then to calculate ` `        ``// product for next iteration, it should ` `        ``// be set to 1 as maximum product ` `        ``// subarray does not include 0. ` `        ``// The minimum possible value ` `        ``// to be considered in maximum product ` `        ``// subarray is already stored in minval, ` `        ``// so when maxval is negative it is set to 1. ` `        ``if` `(``\$maxval` `<= 0)  ` `        ``{ ` `            ``\$maxval` `= 1; ` `        ``} ` `    ``} ` ` `  `    ``return` `\$ans``; ` `} ` ` `  `// Driver Code ` `\$arr` `= ``array``( 0, -4, 0, -2 ); ` `\$n` `= sizeof(``\$arr``); ` `echo` `findMaxProduct(``\$arr``, ``\$n``); ` ` `  `// This code is contributed by ita_c ` `?> `

Output:

``` 0
```

Time Complexity: O(n)
Auxiliary Space: O(1)