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 maximum product to be negative or zero, the values of variable maxval (maximum product upto current element) and minval (minimum product upto 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: Update maxval with zero in case all other elements are negative then this is the maximum possible product so far. Update minval with 1 as subarray product with zero as element in it will be zero, which is not minimum. So to include next element exclude this zero from minval by setting it 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++ program to find maximum subarray product.
#include <bits/stdc++.h>

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;
}
Output:  0

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



My Personal Notes arrow_drop_up

A Programmer and A Machine learning Enthusiast

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.




Article Tags :
Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.

Recommended Posts:



3.6 Average Difficulty : 3.6/5.0
Based on 5 vote(s)






User Actions