Maximum Product Subarray | Set 2 (Using Two Traversals)

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.

Examples :

Input: arr[] = {6, -3, -10, 0, 2}
Output:   180  // The subarray is {6, -3, -10}

Input: arr[] = {-1, -3, -10, 0, 60}
Output:   60  // The subarray is {60}

Input: arr[] = {-1, -2, -3, 4}
Output:   24  // The subarray is {-2, -3, 4}

Input: arr[] = {-10}
Output:   0  // An empty array is also subarray
             // and product of empty subarray is
             // considered as 0.



We have discussed a solution of this problem here.
In this post an interesting solution is discussed. The idea is based on the fact that overall maximum product is maximum of following two:

  1. Maximum product in left to right traversal.
  2. Maximum product in right to left traversal

For example, consider the above third sample input {-1, -2, -3, 4}. If we traverse the array only in forward direction (considering -1 as part of output), maximum product will be 2. If we traverse the array in backward direction (considering 4 as part of output), maximum product will be 24 i.e; { -2, -3, 4}.

One important thing is to handle 0’s. We need to compute fresh forward (or backward) sum whenever we see 0.

Below is the implementation of above idea :

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find maximum product subarray
#include<bits/stdc++.h>
using namespace std;
  
// Function for maximum product
int max_product(int arr[], int n)
{
    // Initialize maximum products in forward and
    // backward directions
    int max_fwd = INT_MIN, max_bkd = INT_MIN;
  
    // Initialize current product
    int max_till_now = 1;
  
    // max_fwd for maximum contiguous product in
    // forward direction
    // max_bkd for maximum contiguous product in
    // backward direction
    // iterating within forward direction in array
    for (int i=0; i<n; i++)
    {
        // if arr[i]==0, it is breaking condition
        // for contiguos subarray
        max_till_now = max_till_now*arr[i];
        if (max_till_now == 0)
        {
             max_till_now = 1;
            continue;
        }
        if (max_fwd < max_till_now) // update max_fwd
            max_fwd = max_till_now;
    }
  
     max_till_now = 1;
  
    // iterating within backward direction in array
    for (int i=n-1; i>=0; i--)
    {
        max_till_now = max_till_now * arr[i];
        if (max_till_now == 0)
        {
            max_till_now = 1;
            continue;
        }
  
        // update max_bkd
        if (max_bkd < max_till_now)
            max_bkd = max_till_now;
    }
  
    // return max of max_fwd and max_bkd
    int res =  max(max_fwd, max_bkd);
  
    // Product should not be nagative.
    // (Product of an empty subarray is
    // considered as 0)
    return max(res, 0);
}
  
// Driver Program to test above function
int main()
{
    int arr[] = {-1, -2, -3, 4};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << max_product(arr, n) << endl;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find
// maximum product subarray
import java.io.*;
  
class GFG 
{
  
// Function for maximum product
static int max_product(int arr[], int n)
{
    // Initialize maximum products in 
    // forward and backward directions
    int max_fwd = Integer.MIN_VALUE, 
        max_bkd = Integer.MIN_VALUE;
  
    // Initialize current product
    int max_till_now = 1;
  
    // max_fwd for maximum contiguous 
    // product in forward direction
    // max_bkd for maximum contiguous 
    // product in backward direction
    // iterating within forward 
    // direction in array
    for (int i = 0; i < n; i++)
    {
        // if arr[i]==0, it is breaking 
        // condition for contiguos subarray
        max_till_now = max_till_now * arr[i];
        if (max_till_now == 0)
        {
            max_till_now = 1;
            continue;
        }
          
        // update max_fwd
        if (max_fwd < max_till_now) 
            max_fwd = max_till_now;
    }
  
    max_till_now = 1;
  
    // iterating within backward 
    // direction in array
    for (int i = n - 1; i >= 0; i--)
    {
        max_till_now = max_till_now * arr[i];
        if (max_till_now == 0)
        {
            max_till_now = 1;
            continue;
        }
  
        // update max_bkd
        if (max_bkd < max_till_now)
            max_bkd = max_till_now;
    }
  
    // return max of max_fwd and max_bkd
    int res = Math. max(max_fwd, max_bkd);
  
    // Product should not be nagative.
    // (Product of an empty subarray is
    // considered as 0)
    return Math.max(res, 0);
}
  
// Driver Code
public static void main (String[] args) 
{
    int arr[] = {-1, -2, -3, 4};
    int n = arr.length;
    System.out.println( max_product(arr, n) );
}
}
  
// This code is contributed by anuj_67.

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find
# maximum product subarray 
import sys
  
# Function for maximum product 
def max_product(arr, n):
  
    # Initialize maximum products 
    # in forward and backward directions 
    max_fwd = -sys.maxsize - 1
    max_bkd = -sys.maxsize - 1
  
    # Initialize current product 
    max_till_now = 1
  
    # max_fwd for maximum contiguous
    # product in forward direction 
    # max_bkd for maximum contiguous 
    # product in backward direction 
    # iterating within forward 
    # direction in array 
    for i in range(n): 
      
        # if arr[i]==0, it is breaking 
        # condition for contiguos subarray 
        max_till_now = max_till_now * arr[i]
        if (max_till_now == 0):
            max_till_now = 1
            continue
          
        if (max_fwd < max_till_now): #update max_fwd 
            max_fwd = max_till_now 
      
    max_till_now = 1
  
    # iterating within backward
    # direction in array 
    for i in range(n - 1, -1, -1):
        max_till_now = max_till_now * arr[i] 
          
        if (max_till_now == 0): 
            max_till_now = 1
            continue
  
        # update max_bkd 
        if (max_bkd < max_till_now) : 
            max_bkd = max_till_now 
  
    # return max of max_fwd and max_bkd 
    res = max(max_fwd, max_bkd) 
  
    # Product should not be nagative. 
    # (Product of an empty subarray is 
    # considered as 0) 
    return max(res, 0
  
# Driver Code
arr = [-1, -2, -3, 4
n = len(arr) 
print(max_product(arr, n))
  
# This code is contributed 
# by Yatin Gupta 

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find maximum product
// subarray
using System; 
  
class GFG {
  
    // Function for maximum product
    static int max_product(int []arr, int n)
    {
          
        // Initialize maximum products in 
        // forward and backward directions
        int max_fwd = int.MinValue, 
            max_bkd = int.MinValue;
      
        // Initialize current product
        int max_till_now = 1;
      
        // max_fwd for maximum contiguous 
        // product in forward direction
        // max_bkd for maximum contiguous 
        // product in backward direction
        // iterating within forward 
        // direction in array
        for (int i = 0; i < n; i++)
        {
              
            // if arr[i]==0, it is breaking 
            // condition for contiguos subarray
            max_till_now = max_till_now * arr[i];
              
            if (max_till_now == 0)
            {
                max_till_now = 1;
                continue;
            }
              
            // update max_fwd
            if (max_fwd < max_till_now) 
                max_fwd = max_till_now;
        }
      
        max_till_now = 1;
      
        // iterating within backward 
        // direction in array
        for (int i = n - 1; i >= 0; i--)
        {
            max_till_now = max_till_now * arr[i];
            if (max_till_now == 0)
            {
                max_till_now = 1;
                continue;
            }
      
            // update max_bkd
            if (max_bkd < max_till_now)
                max_bkd = max_till_now;
        }
      
        // return max of max_fwd and max_bkd
        int res = Math. Max(max_fwd, max_bkd);
      
        // Product should not be nagative.
        // (Product of an empty subarray is
        // considered as 0)
        return Math.Max(res, 0);
    }
      
    // Driver Code
    public static void Main () 
    {
        int []arr = {-1, -2, -3, 4};
        int n = arr.Length;
          
        Console.Write( max_product(arr, n) );
    }
}
  
// This code is contributed by nitin mittal.

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to find maximum 
// product subarray
  
// Function for maximum product
function max_product( $arr, $n)
{
      
    // Initialize maximum products
    // in forward and backward
    // directions
    $max_fwd = PHP_INT_MIN; 
    $max_bkd = PHP_INT_MIN;
  
    // Initialize current product
    $max_till_now = 1;
  
    // max_fwd for maximum contiguous 
    // product in forward direction
    // max_bkd for maximum contiguous
    // product in backward direction
    // iterating within forward direction
    // in array
    for ($i = 0; $i < $n; $i++)
    {
          
        // if arr[i]==0, it is
        // breaking condition
        // for contiguos subarray
        $max_till_now = $max_till_now * $arr[$i];
        if ($max_till_now == 0)
        {
            $max_till_now = 1;
            continue;
        }
          
        // update max_fwd
        if ($max_fwd < $max_till_now
            $max_fwd = $max_till_now;
    }
  
    $max_till_now = 1;
  
    // iterating within backward 
    // direction in array
    for($i = $n - 1; $i >= 0; $i--)
    {
        $max_till_now = $max_till_now * $arr[$i];
        if ($max_till_now == 0)
        {
            $max_till_now = 1;
            continue;
        }
  
        // update max_bkd
        if ($max_bkd < $max_till_now)
            $max_bkd = $max_till_now;
    }
  
    // return max of max_fwd
    // and max_bkd
    $res = max($max_fwd, $max_bkd);
  
    // Product should not be nagative.
    // (Product of an empty subarray is
    // considered as 0)
    return max($res, 0);
}
  
    // Driver Code
    $arr = array(-1, -2, -3, 4);
    $n = count($arr);
    echo max_product($arr, $n);
  
// This code is contributed by anuj_67.
?>

chevron_right



Output :

24

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

Note that the above solution requires two traversals of array while the previous solution requires only one traversal.

This article is contributed by Shashank Mishra (Gullu). 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.



My Personal Notes arrow_drop_up

Improved By : vt_m, nitin mittal, YatinGupta



Article Tags :
Practice Tags :


2


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