Open In App

Maximize Sum possible by subtracting same value from all elements of a Subarray of the given Array

Last Updated : 28 Nov, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array a[] consisting of N integers, the task is to find the maximum possible sum that can be achieved by deducting any value, say X, from all elements of a subarray.

Examples:

Input: N = 3, a[] = {80, 48, 82} 
Output: 144 
Explanation: 
48 can be deducted from each array element. Therefore, sum obtained = 48 * 3 = 144
Input: N = a[] = {8, 40, 77} 
Output: 80 
Explanation: 
Subtracting 8 from all array elements generates sum 24. 
Subtracting 40 from a[1] and a[2] generates sum 80. 
Subtracting 77 from a[2] generates sum 77. 
Therefore, maximum possible sum is 80.

Approach: 
Follow the steps below to solve the problem:

  • Traverse the array
  • For every element, find the element which is nearest smaller on its left and nearest smaller on its right.
  • Calculate the sum possible by that element calculating current_element * ( j – i – 1 ) where j and i are the indices of the nearest smaller numbers on the left and right respectively.
  • Find the maximum possible sum among all of them.

Below is the implementation of the above approach:

C++




// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to generate previous smaller
// element for each array element
vector<int> findPrevious(vector<int> a, int n)
{
    vector<int> ps(n);
 
    // The first element has no
    // previous smaller
    ps[0] = -1;
 
    // Stack to keep track of elements
    // that have occurred previously
    stack<int> Stack;
 
    // Push the first index
    Stack.push(0);
     
    for(int i = 1; i < n; i++)
    {
         
        // Pop all the elements until the previous
        // element is smaller than current element
        while (Stack.size() > 0 &&
             a[Stack.top()] >= a[i])
            Stack.pop();
 
        // Store the previous smaller element
        ps[i] = Stack.size() > 0 ?
                Stack.top() : -1;
 
        // Push the index of the current element
        Stack.push(i);
    }
 
    // Return the array
    return ps;
}
 
// Function to generate next smaller element
// for each array element
vector<int> findNext(vector<int> a, int n)
{
    vector<int> ns(n);
 
    ns[n - 1] = n;
 
    // Stack to keep track of elements
    // that have occurring next
    stack<int> Stack;
    Stack.push(n - 1);
 
    // Iterate in reverse order
    // for calculating next smaller
    for(int i = n - 2; i >= 0; i--)
    {
         
        // Pop all the elements until the
        // next element is smaller
        // than current element
        while (Stack.size() > 0 &&
             a[Stack.top()] >= a[i])
            Stack.pop();
 
        // Store the next smaller element
        ns[i] = Stack.size() > 0 ?
                Stack.top() : n;
 
        // Push the index of the current element
        Stack.push(i);
    }
 
    // Return the array
    return ns;
}
 
// Function to find the maximum sum by
// subtracting same value from all
// elements of a Subarray
int findMaximumSum(vector<int> a, int n)
{
     
    // Stores previous smaller element
    vector<int> prev_smaller = findPrevious(a, n);
 
    // Stores next smaller element
    vector<int> next_smaller = findNext(a, n);
 
    int max_value = 0;
    for(int i = 0; i < n; i++)
    {
         
        // Calculate contribution
        // of each element
        max_value = max(max_value, a[i] *
                       (next_smaller[i] -
                        prev_smaller[i] - 1));
    }
 
    // Return answer
    return max_value;
}
 
// Driver Code   
int main()
{
    int n = 3;
    vector<int> a{ 80, 48, 82 };
     
    cout << findMaximumSum(a, n);
     
    return 0;
}
 
// This code is contributed by divyeshrabadiya07


Java




// Java Program to implement
// the above approach
import java.util.*;
 
public class GFG {
 
    // Function to find the maximum sum by
    // subtracting same value from all
    // elements of a Subarray
    public static int findMaximumSum(int[] a, int n)
    {
        // Stores previous smaller element
        int prev_smaller[] = findPrevious(a, n);
 
        // Stores next smaller element
        int next_smaller[] = findNext(a, n);
 
        int max_value = 0;
        for (int i = 0; i < n; i++) {
 
            // Calculate contribution
            // of each element
            max_value
                = Math.max(max_value,
                        a[i] * (next_smaller[i]
                                - prev_smaller[i] - 1));
        }
 
        // Return answer
        return max_value;
    }
 
    // Function to generate previous smaller element
    // for each array element
    public static int[] findPrevious(int[] a, int n)
    {
        int ps[] = new int[n];
 
        // The first element has no
        // previous smaller
        ps[0] = -1;
 
        // Stack to keep track of elements
        // that have occurred previously
        Stack<Integer> stack = new Stack<>();
 
        // Push the first index
        stack.push(0);
        for (int i = 1; i < a.length; i++) {
 
            // Pop all the elements until the previous
            // element is smaller than current element
            while (stack.size() > 0
                && a[stack.peek()] >= a[i])
                stack.pop();
 
            // Store the previous smaller element
            ps[i] = stack.size() > 0 ? stack.peek() : -1;
 
            // Push the index of the current element
            stack.push(i);
        }
 
        // Return the array
        return ps;
    }
 
    // Function to generate next smaller element
    // for each array element
    public static int[] findNext(int[] a, int n)
    {
        int ns[] = new int[n];
 
        ns[n - 1] = n;
 
        // Stack to keep track of elements
        // that have occurring next
        Stack<Integer> stack = new Stack<>();
        stack.push(n - 1);
 
        // Iterate in reverse order
        // for calculating next smaller
        for (int i = n - 2; i >= 0; i--) {
 
            // Pop all the elements until the
            // next element is smaller
            // than current element
            while (stack.size() > 0
                && a[stack.peek()] >= a[i])
                stack.pop();
 
            // Store the next smaller element
            ns[i] = stack.size() > 0 ? stack.peek()
                                    : a.length;
 
            // Push the index of the current element
            stack.push(i);
        }
 
        // Return the array
        return ns;
    }
 
    // Driver Code
    public static void main(String args[])
    {
        int n = 3;
        int a[] = { 80, 48, 82 };
        System.out.println(findMaximumSum(a, n));
    }
}


Python3




# Python3 program to implement
# the above approach
 
# Function to find the maximum sum by
# subtracting same value from all
# elements of a Subarray
def findMaximumSum(a, n):
     
    # Stores previous smaller element
    prev_smaller = findPrevious(a, n)
     
    # Stores next smaller element
    next_smaller = findNext(a, n)
     
    max_value = 0
    for i in range(n):
         
        # Calculate contribution
        # of each element
        max_value = max(max_value, a[i] *
                    (next_smaller[i] -
                        prev_smaller[i] - 1))
         
    # Return answer
    return max_value
 
# Function to generate previous smaller
# element for each array element
def findPrevious(a, n):
     
    ps = [0] * n
     
    # The first element has no
    # previous smaller
    ps[0] = -1
     
    # Stack to keep track of elements
    # that have occurred previously
    stack = []
     
    # Push the first index
    stack.append(0)
     
    for i in range(1, n):
         
        # Pop all the elements until the previous
        # element is smaller than current element
        while len(stack) > 0 and a[stack[-1]] >= a[i]:
            stack.pop()
             
        # Store the previous smaller element
        ps[i] = stack[-1] if len(stack) > 0 else -1
         
        # Push the index of the current element
        stack.append(i)
         
    # Return the array
    return ps
 
# Function to generate next smaller
# element for each array element
def findNext(a, n):
     
    ns = [0] * n
    ns[n - 1] = n
     
    # Stack to keep track of elements
    # that have occurring next
    stack = []
    stack.append(n - 1)
     
    # Iterate in reverse order
    # for calculating next smaller
    for i in range(n - 2, -1, -1):
         
        # Pop all the elements until the
        # next element is smaller
        # than current element
        while (len(stack) > 0 and
                a[stack[-1]] >= a[i]):
            stack.pop()
         
        # Store the next smaller element
        ns[i] = stack[-1] if len(stack) > 0 else n
         
        # Push the index of the current element
        stack.append(i)
         
    # Return the array
    return ns
 
# Driver code
n = 3
a = [ 80, 48, 82 ]
 
print(findMaximumSum(a, n))
 
# This code is contributed by Stuti Pathak


C#




// C# Program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Function to find the maximum sum by
// subtracting same value from all
// elements of a Subarray
public static int findMaximumSum(int[] a, int n)
{
    // Stores previous smaller element
    int []prev_smaller = findPrevious(a, n);
 
    // Stores next smaller element
    int []next_smaller = findNext(a, n);
 
    int max_value = 0;
    for (int i = 0; i < n; i++)
    {
 
    // Calculate contribution
    // of each element
    max_value = Math.Max(max_value,
                a[i] * (next_smaller[i] -
                        prev_smaller[i] - 1));
    }
 
    // Return answer
    return max_value;
}
 
// Function to generate previous smaller element
// for each array element
public static int[] findPrevious(int[] a, int n)
{
    int []ps = new int[n];
 
    // The first element has no
    // previous smaller
    ps[0] = -1;
 
    // Stack to keep track of elements
    // that have occurred previously
    Stack<int> stack = new Stack<int>();
 
    // Push the first index
    stack.Push(0);
    for (int i = 1; i < a.Length; i++)
    {
 
    // Pop all the elements until the previous
    // element is smaller than current element
    while (stack.Count > 0 &&
            a[stack.Peek()] >= a[i])
        stack.Pop();
 
    // Store the previous smaller element
    ps[i] = stack.Count > 0 ? stack.Peek() : -1;
 
    // Push the index of the current element
    stack.Push(i);
    }
 
    // Return the array
    return ps;
}
 
// Function to generate next smaller element
// for each array element
public static int[] findNext(int[] a, int n)
{
    int []ns = new int[n];
 
    ns[n - 1] = n;
 
    // Stack to keep track of elements
    // that have occurring next
    Stack<int> stack = new Stack<int>();
    stack.Push(n - 1);
 
    // Iterate in reverse order
    // for calculating next smaller
    for (int i = n - 2; i >= 0; i--)
    {
 
    // Pop all the elements until the
    // next element is smaller
    // than current element
    while (stack.Count > 0 &&
            a[stack.Peek()] >= a[i])
        stack.Pop();
 
    // Store the next smaller element
    ns[i] = stack.Count > 0 ? stack.Peek()
        : a.Length;
 
    // Push the index of the current element
    stack.Push(i);
    }
 
    // Return the array
    return ns;
}
 
// Driver Code
public static void Main(String []args)
{
    int n = 3;
    int []a = { 80, 48, 82 };
    Console.WriteLine(findMaximumSum(a, n));
}
}
 
// This code is contributed by Amit Katiyar


Javascript




<script>
// javascript Program to implement
// the above approach
 
    // Function to find the maximum sum by
    // subtracting same value from all
    // elements of a Subarray
    function findMaximumSum(a ,n)
    {
     
        // Stores previous smaller element
        var prev_smaller = findPrevious(a, n);
 
        // Stores next smaller element
        var next_smaller = findNext(a, n);
 
        var max_value = 0;
        for (var i = 0; i < n; i++)
        {
 
            // Calculate contribution
            // of each element
            max_value = Math.max(max_value, a[i] * (next_smaller[i] - prev_smaller[i] - 1));
        }
 
        // Return answer
        return max_value;
    }
 
    // Function to generate previous smaller element
    // for each array element
      function findPrevious(a , n) {
        var ps = Array(n).fill(0);
 
        // The first element has no
        // previous smaller
        ps[0] = -1;
 
        // Stack to keep track of elements
        // that have occurred previously
        let stack = Array();
 
        // Push the first index
        stack.push(0);
        for (var i = 1; i < a.length; i++) {
 
            // Pop all the elements until the previous
            // element is smaller than current element
            while (stack.length > 0 && a[stack[stack.length-1]] >= a[i])
                stack.pop();
 
            // Store the previous smaller element
            ps[i] = stack.length > 0 ?stack[stack.length-1] : -1;
 
            // Push the index of the current element
            stack.push(i);
        }
 
        // Return the array
        return ps;
    }
 
    // Function to generate next smaller element
    // for each array element
      function findNext(a , n) {
        var ns = Array(n).fill(0);
 
        ns[n - 1] = n;
 
        // Stack to keep track of elements
        // that have occurring next
        var stack = Array();
        stack.push(n - 1);
 
        // Iterate in reverse order
        // for calculating next smaller
        for (var i = n - 2; i >= 0; i--) {
 
            // Pop all the elements until the
            // next element is smaller
            // than current element
            while (stack.length > 0 && a[stack[stack.length-1]] >= a[i])
                stack.pop();
 
            // Store the next smaller element
            ns[i] = stack.length > 0 ? stack[stack.length-1] : a.length;
 
            // Push the index of the current element
            stack.push(i);
        }
 
        // Return the array
        return ns;
    }
 
    // Driver Code
        var n = 3;
        var a = [ 80, 48, 82 ];
        document.write(findMaximumSum(a, n));
 
// This code is contributed by gauravrajput1
</script>


Output: 

144

Time Complexity: O(N) 
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads