Maximize product of subarray sum with its minimum element - GeeksforGeeks

21 May, 2021
Given an array arr[] consisting of N positive integers, the task is to find the maximum product of subarray sum with the minimum element of that subarray.
Examples:
Input: arr[] = {3, 1, 6, 4, 5, 2}Output: 60Explanation:The required maximum product can be obtained using subarray {6, 4, 5}Therefore, maximum product = (6 + 4 + 5) * (4) = 60
Input: arr[] = {4, 1, 2, 9, 3}Output: 81Explanation:The required maximum product can be obtained using subarray {9}Maximum product = (9)* (9) = 81
Naive Approach: The simplest approach to solve the problem is to generate all subarrays of the given array and for each subarray, calculate the sum of the subarray, and multiply it with the minimum element in the subarray. Update the maximum product by comparing it with the product calculated. Finally, print the maximum product obtained after processing all the subarray.
 Time Complexity: O(N3)Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized using a Stack and Prefix Sum Array. The idea is to use the stack to get the index of nearest smaller elements on the left and right of each element. Now, using these, the required product can be obtained. Follow the steps below to solve the problem:
Initialize an array presum[] to store all the resultant prefix sum array of the given array.
Initialize two arrays l[] and r[] to store the index of the nearest left and right smaller elements respectively.
For every element arr[i], calculate l[i] and r[i] using a stack.
Traverse the given array and for each index i, the product can be calculated by:
arr[i] * (presum[r[i]] – presum[l[i]-1])
Print the maximum product after completing all the above steps
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program to implement// the above approach#include<bits/stdc++.h>using namespace std; // Function to find the// maximum product possiblevoid maxValue(int a[], int n){         // Stores prefix sum    int presum[n];     presum[0] = a[0];     // Find the prefix sum array    for(int i = 1; i < n; i++)    {        presum[i] = presum[i - 1] + a[i];    }     // l[] and r[] stores index of    // nearest smaller elements on    // left and right respectively    int l[n], r[n];     stack<int> st;     // Find all left index    for(int i = 1; i < n; i++)    {                 // Until stack is non-empty        // & top element is greater        // than the current element        while (!st.empty() &&              a[st.top()] >= a[i])            st.pop();         // If stack is empty        if (!st.empty())            l[i] = st.top() + 1;        else            l[i] = 0;         // Push the current index i        st.push(i);    }     // Reset stack    while(!st.empty())    st.pop();     // Find all right index    for(int i = n - 1; i >= 0; i--)    {                 // Until stack is non-empty        // & top element is greater        // than the current element        while (!st.empty() &&              a[st.top()] >= a[i])            st.pop();             if (!st.empty())                r[i] = st.top() - 1;            else                r[i] = n - 1;         // Push the current index i        st.push(i);    }     // Stores the maximum product    int maxProduct = 0;     int tempProduct;     // Iterate over the range [0, n)    for(int i = 0; i < n; i++)    {                 // Calculate the product        tempProduct = a[i] * (presum[r[i]] -                     (l[i] == 0 ? 0 :                    presum[l[i] - 1]));         // Update the maximum product        maxProduct = max(maxProduct,                        tempProduct);    }     // Return the maximum product    cout << maxProduct;} // Driver Codeint main(){         // Given array    int n = 6;    int arr[] = { 3, 1, 6, 4, 5, 2 };     // Function call    maxValue(arr, n);} // This code is contributed by grand_master
// Java program to implement// the above approach import java.util.*; class GFG {     // Function to find the    // maximum product possible    public static void    maxValue(int[] a, int n)    {         // Stores prefix sum        int[] presum = new int[n];         presum[0] = a[0];         // Find the prefix sum array        for (int i = 1; i < n; i++) {             presum[i] = presum[i - 1] + a[i];        }         // l[] and r[] stores index of        // nearest smaller elements on        // left and right respectively        int[] l = new int[n], r = new int[n];         Stack<Integer> st = new Stack<>();         // Find all left index        for (int i = 1; i < n; i++) {             // Until stack is non-empty            // & top element is greater            // than the current element            while (!st.isEmpty()                   && a[st.peek()] >= a[i])                st.pop();             // If stack is empty            if (!st.isEmpty())                l[i] = st.peek() + 1;            else                l[i] = 0;             // Push the current index i            st.push(i);        }         // Reset stack        st.clear();         // Find all right index        for (int i = n - 1; i >= 0; i--) {             // Until stack is non-empty            // & top element is greater            // than the current element            while (!st.isEmpty()                   && a[st.peek()] >= a[i])                st.pop();             if (!st.isEmpty())                r[i] = st.peek() - 1;            else                r[i] = n - 1;             // Push the current index i            st.push(i);        }         // Stores the maximum product        int maxProduct = 0;         int tempProduct;         // Iterate over the range [0, n)        for (int i = 0; i < n; i++) {             // Calculate the product            tempProduct                = a[i]                  * (presum[r[i]]                     - (l[i] == 0 ? 0                                  : presum[l[i] - 1]));             // Update the maximum product            maxProduct                = Math.max(maxProduct,                           tempProduct);        }         // Return the maximum product        System.out.println(maxProduct);    }     // Driver Code    public static void main(String[] args)    {        // Given array        int[] arr = { 3, 1, 6, 4, 5, 2 };         // Function Call        maxValue(arr, arr.length);    }}
# Python3 program to implement# the above approach # Function to find the# maximum product possibledef maxValue(a, n):         # Stores prefix sum    presum = [0 for i in range(n)]     presum[0] = a[0]     # Find the prefix sum array    for i in range(1, n, 1):        presum[i] = presum[i - 1] + a[i]     # l[] and r[] stores index of    # nearest smaller elements on    # left and right respectively    l = [0 for i in range(n)]    r = [0 for i in range(n)]     st = []     # Find all left index    for i in range(1, n):                 # Until stack is non-empty        # & top element is greater        # than the current element        while (len(st) and          a[st[len(st) - 1]] >= a[i]):            st.remove(st[len(st) - 1])                     # If stack is empty        if (len(st)):            l[i] = st[len(st) - 1] + 1;        else:            l[i] = 0         # Push the current index i        st.append(i)     # Reset stack    while(len(st)):        st.remove(st[len(st) - 1])     # Find all right index    i = n - 1    while(i >= 0):                 # Until stack is non-empty        # & top element is greater        # than the current element        while (len(st) and          a[st[len(st) - 1]] >= a[i]):            st.remove(st[len(st) - 1])             if (len(st)):                r[i] = st[len(st) - 1] - 1            else:                r[i] = n - 1         # Push the current index i        st.append(i)        i -= 1     # Stores the maximum product    maxProduct = 0     # Iterate over the range [0, n)    for i in range(n):                 # Calculate the product        if l[i] == 0:            tempProduct = (a[i] *                    presum[r[i]])        else:            tempProduct = (a[i] *                   (presum[r[i]] -                    presum[l[i] - 1]))         # Update the maximum product        maxProduct = max(maxProduct,                        tempProduct)     # Return the maximum product    print(maxProduct) # Driver Codeif __name__ == '__main__':         # Given array    n = 6    arr =  [ 3, 1, 6, 4, 5, 2 ]         # Function call    maxValue(arr, n) # This code is contributed by SURENDRA_GANGWAR
// C# program to implement// the above approachusing System;using System.Collections.Generic; class GFG{     // Function to find the// maximum product possiblepublic static void maxValue(int[] a,                            int n){         // Stores prefix sum    int[] presum = new int[n];     presum[0] = a[0];     // Find the prefix sum array    for(int i = 1; i < n; i++)    {        presum[i] = presum[i - 1] + a[i];    }     // l[] and r[] stores index of    // nearest smaller elements on    // left and right respectively    int[] l = new int[n], r = new int[n];         Stack<int> st = new Stack<int>();     // Find all left index    for(int i = 1; i < n; i++)    {                 // Until stack is non-empty        // & top element is greater        // than the current element        while (st.Count > 0 &&           a[st.Peek()] >= a[i])            st.Pop();         // If stack is empty        if (st.Count > 0)            l[i] = st.Peek() + 1;        else            l[i] = 0;         // Push the current index i        st.Push(i);    }     // Reset stack    st.Clear();     // Find all right index    for(int i = n - 1; i >= 0; i--)    {                 // Until stack is non-empty        // & top element is greater        // than the current element        while (st.Count > 0 &&           a[st.Peek()] >= a[i])            st.Pop();         if (st.Count > 0)            r[i] = st.Peek() - 1;        else            r[i] = n - 1;         // Push the current index i        st.Push(i);    }     // Stores the maximum product    int maxProduct = 0;     int tempProduct;     // Iterate over the range [0, n)    for(int i = 0; i < n; i++)    {                 // Calculate the product        tempProduct = a[i] * (presum[r[i]] -                     (l[i] == 0 ? 0 :                     presum[l[i] - 1]));         // Update the maximum product        maxProduct = Math.Max(maxProduct,                             tempProduct);    }     // Return the maximum product    Console.WriteLine(maxProduct);} // Driver codestatic void Main(){         // Given array    int[] arr = { 3, 1, 6, 4, 5, 2 };         // Function call    maxValue(arr, arr.Length);}} // This code is contributed by divyeshrabadiya07
<script> // Javascript program to implement// the above approach // Function to find the// maximum product possiblefunction maxValue(a, n){         // Stores prefix sum    var presum = Array(n);     presum[0] = a[0];     // Find the prefix sum array    for(var i = 1; i < n; i++)    {        presum[i] = presum[i - 1] + a[i];    }     // l[] and r[] stores index of    // nearest smaller elements on    // left and right respectively    var l = Array(n).fill(0), r = Array(n).fill(0);     var st = [];     // Find all left index    for(var i = 1; i < n; i++)    {                 // Until stack is non-empty        // & top element is greater        // than the current element        while (st.length!=0 &&              a[st[st.length-1]] >= a[i])            st.pop();         // If stack is empty        if (st.length!=0)            l[i] = st[st.length-1] + 1;        else            l[i] = 0;         // Push the current index i        st.push(i);    }     // Reset stack    while(st.length!=0)        st.pop();     // Find all right index    for(var i = n - 1; i >= 0; i--)    {                 // Until stack is non-empty        // & top element is greater        // than the current element        while (st.length!=0 &&              a[st[st.length-1]] >= a[i])            st.pop();             if (st.length!=0)                r[i] = st[st.length-1] - 1;            else                r[i] = n - 1;         // Push the current index i        st.push(i);    }     // Stores the maximum product    var maxProduct = 0;     var tempProduct;     // Iterate over the range [0, n)    for(var i = 0; i < n; i++)    {                 // Calculate the product        tempProduct = a[i] * (presum[r[i]] -                     (l[i] == 0 ? 0 :                    presum[l[i] - 1]));         // Update the maximum product        maxProduct = Math.max(maxProduct,                        tempProduct);    }     // Return the maximum product    document.write( maxProduct);} // Driver Code// Given arrayvar n = 6;var arr = [3, 1, 6, 4, 5, 2];// Function callmaxValue(arr, n); </script>
60
 
Time Complexity: O(N)Auxiliary Space: O(N)
divyeshrabadiya07
grand_master
SURENDRA_GANGWAR
importantly
Amazon
interview-preparation
prefix-sum
subarray
subarray-sum
Arrays
Stack
Amazon
prefix-sum
Arrays
Stack
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Stack Data Structure (Introduction and Program)
Top 50 Array Coding Problems for Interviews
Introduction to Arrays
Multidimensional Arrays in Java
Linear Search
Stack Data Structure (Introduction and Program)
Stack Class in Java
Stack in Python
Check for Balanced Brackets in an expression (well-formedness) using Stack
Inorder Tree Traversal without Recursion