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++ 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 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 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# 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 |
<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> |
144
Time Complexity: O(N)
Auxiliary Space: O(N)