Find maximum equal sum of every three stacks
Given three stacks of the positive numbers, the task is to find the possible equal maximum sum of the stacks with the removal of top elements allowed. Stacks are represented as an array, and the first index of the array represent the top element of the stack.
Examples:
Input : stack1[] = { 3, 10}
stack2[] = { 4, 5 }
stack3[] = { 2, 1 }
Output : 0
Sum can only be equal after removing all elements
from all stacks.
Method 1:
The idea is to compare the sum of each stack, if they are not same, remove the top element of the stack having the maximum sum.
Algorithm for solving this problem:
- Find the sum of all elements of in individual stacks.
- If the sum of all three stacks is the same, then this is the maximum sum.
- Else remove the top element of the stack having the maximum sum among three of stacks. Repeat step 1 and step 2.
The approach works because elements are positive. To make sum equal, we must remove some element from stack having more sum, and we can only remove from the top.
Below is the implementation of this approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxSum( int stack1[], int stack2[], int stack3[], int n1,
int n2, int n3)
{
int sum1 = 0, sum2 = 0, sum3 = 0;
for ( int i = 0; i < n1; i++)
sum1 += stack1[i];
for ( int i = 0; i < n2; i++)
sum2 += stack2[i];
for ( int i = 0; i < n3; i++)
sum3 += stack3[i];
int top1 = 0, top2 = 0, top3 = 0;
while (1) {
if (top1 == n1 || top2 == n2 || top3 == n3)
return 0;
if (sum1 == sum2 && sum2 == sum3)
return sum1;
if (sum1 >= sum2 && sum1 >= sum3)
sum1 -= stack1[top1++];
else if (sum2 >= sum1 && sum2 >= sum3)
sum2 -= stack2[top2++];
else if (sum3 >= sum2 && sum3 >= sum1)
sum3 -= stack3[top3++];
}
}
int main()
{
int stack1[] = { 3, 2, 1, 1, 1 };
int stack2[] = { 4, 3, 2 };
int stack3[] = { 1, 1, 4, 1 };
int n1 = sizeof (stack1) / sizeof (stack1[0]);
int n2 = sizeof (stack2) / sizeof (stack2[0]);
int n3 = sizeof (stack3) / sizeof (stack3[0]);
cout << maxSum(stack1, stack2, stack3, n1, n2, n3)
<< endl;
return 0;
}
|
Java
class GFG {
public static int maxSum( int stack1[], int stack2[],
int stack3[], int n1, int n2,
int n3)
{
int sum1 = 0 , sum2 = 0 , sum3 = 0 ;
for ( int i= 0 ; i < n1; i++)
sum1 += stack1[i];
for ( int i= 0 ; i < n2; i++)
sum2 += stack2[i];
for ( int i= 0 ; i < n3; i++)
sum3 += stack3[i];
int top1 = 0 , top2 = 0 , top3 = 0 ;
int ans = 0 ;
while ( true )
{
if (top1 == n1 || top2 == n2 || top3 == n3)
return 0 ;
if (sum1 == sum2 && sum2 == sum3)
return sum1;
if (sum1 >= sum2 && sum1 >= sum3)
sum1 -= stack1[top1++];
else if (sum2 >= sum1 && sum2 >= sum3)
sum2 -= stack2[top2++];
else if (sum3 >= sum2 && sum3 >= sum1)
sum3 -= stack3[top3++];
}
}
public static void main(String[] args)
{
int stack1[] = { 3 , 2 , 1 , 1 , 1 };
int stack2[] = { 4 , 3 , 2 };
int stack3[] = { 1 , 1 , 4 , 1 };
int n1 = stack1.length;
int n2 = stack2.length;
int n3 = stack3.length;
System.out.println(maxSum(stack1, stack2,
stack3, n1, n2, n3));
}
}
|
Python3
def maxSum(stack1, stack2, stack3, n1, n2, n3):
sum1, sum2, sum3 = 0 , 0 , 0
for i in range (n1):
sum1 + = stack1[i]
for i in range (n2):
sum2 + = stack2[i]
for i in range (n3):
sum3 + = stack3[i]
top1, top2, top3 = 0 , 0 , 0
ans = 0
while ( 1 ):
if (top1 = = n1 or top2 = = n2 or top3 = = n3):
return 0
if (sum1 = = sum2 and sum2 = = sum3):
return sum1
if (sum1 > = sum2 and sum1 > = sum3):
sum1 - = stack1[top1]
top1 = top1 + 1
else if (sum2 > = sum1 and sum2 > = sum3):
sum2 - = stack2[top2]
top2 = top2 + 1
else if (sum3 > = sum2 and sum3 > = sum1):
sum3 - = stack3[top3]
top3 = top3 + 1
stack1 = [ 3 , 2 , 1 , 1 , 1 ]
stack2 = [ 4 , 3 , 2 ]
stack3 = [ 1 , 1 , 4 , 1 ]
n1 = len (stack1)
n2 = len (stack2)
n3 = len (stack3)
print (maxSum(stack1, stack2, stack3, n1, n2, n3))
|
C#
using System;
class GFG {
public static int maxSum( int [] stack1,
int [] stack2, int [] stack3,
int n1, int n2, int n3)
{
int sum1 = 0, sum2 = 0, sum3 = 0;
for ( int i = 0; i < n1; i++)
sum1 += stack1[i];
for ( int i = 0; i < n2; i++)
sum2 += stack2[i];
for ( int i = 0; i < n3; i++)
sum3 += stack3[i];
int top1 = 0, top2 = 0, top3 = 0;
while ( true ) {
if (top1 == n1 || top2 == n2
|| top3 == n3)
return 0;
if (sum1 == sum2 && sum2 == sum3)
return sum1;
if (sum1 >= sum2 && sum1 >= sum3)
sum1 -= stack1[top1++];
else if (sum2 >= sum1 && sum2 >= sum3)
sum2 -= stack2[top2++];
else if (sum3 >= sum2 && sum3 >= sum1)
sum3 -= stack3[top3++];
}
}
public static void Main()
{
int [] stack1 = { 3, 2, 1, 1, 1 };
int [] stack2 = { 4, 3, 2 };
int [] stack3 = { 1, 1, 4, 1 };
int n1 = stack1.Length;
int n2 = stack2.Length;
int n3 = stack3.Length;
Console.Write(maxSum(stack1, stack2,
stack3, n1, n2, n3));
}
}
|
Javascript
<script>
function maxSum(stack1, stack2,
stack3, n1, n2, n3)
{
let sum1 = 0, sum2 = 0, sum3 = 0;
for (let i = 0; i < n1; i++)
sum1 += stack1[i];
for (let i = 0; i < n2; i++)
sum2 += stack2[i];
for (let i = 0; i < n3; i++)
sum3 += stack3[i];
let top1 = 0, top2 = 0, top3 = 0;
let ans = 0;
while ( true )
{
if (top1 == n1 || top2 == n2 ||
top3 == n3)
return 0;
if (sum1 == sum2 && sum2 == sum3)
return sum1;
if (sum1 >= sum2 && sum1 >= sum3)
sum1 -= stack1[top1++];
else if (sum2 >= sum1 && sum2 >= sum3)
sum2 -= stack2[top2++];
else if (sum3 >= sum2 && sum3 >= sum1)
sum3 -= stack3[top3++];
}
}
let stack1 = [ 3, 2, 1, 1, 1 ];
let stack2 = [ 4, 3, 2 ];
let stack3 = [ 1, 1, 4, 1 ];
let n1 = stack1.length;
let n2 = stack2.length;
let n3 = stack3.length;
document.write(maxSum(stack1, stack2,
stack3, n1, n2, n3));
</script>
|
PHP
<?php
function maxSum( $stack1 , $stack2 , $stack3 ,
$n1 , $n2 , $n3 )
{
$sum1 = 0; $sum2 = 0; $sum3 = 0;
for ( $i = 0; $i < $n1 ; $i ++)
$sum1 += $stack1 [ $i ];
for ( $i = 0; $i < $n2 ; $i ++)
$sum2 += $stack2 [ $i ];
for ( $i = 0; $i < $n3 ; $i ++)
$sum3 += $stack3 [ $i ];
$top1 =0;
$top2 = 0;
$top3 = 0;
$ans = 0;
while (1)
{
if ( $top1 == $n1 || $top2 == $n2 ||
$top3 == $n3 )
return 0;
if ( $sum1 == $sum2 && $sum2 == $sum3 )
return $sum1 ;
if ( $sum1 >= $sum2 && $sum1 >= $sum3 )
$sum1 -= $stack1 [ $top1 ++];
else if ( $sum2 >= $sum1 && $sum2 >= $sum3 )
$sum2 -= $stack2 [ $top2 ++];
else if ( $sum3 >= $sum2 && $sum3 >= $sum1 )
$sum3 -= $stack3 [ $top3 ++];
}
}
$stack1 = array (3, 2, 1, 1, 1);
$stack2 = array (4, 3, 2);
$stack3 = array (1, 1, 4, 1);
$n1 = sizeof( $stack1 );
$n2 = sizeof( $stack2 );
$n3 = sizeof( $stack3 );
echo maxSum( $stack1 , $stack2 ,
$stack3 , $n1 ,
$n2 , $n3 ) ;
?>
|
Time Complexity : O(n1 + n2 + n3) where n1, n2 and n3 are sizes of three stacks.
Auxiliary space: O(1) because using constant space for variables
Method 2: Using suffix sum and unordered_set
The question can be reinterpreted as we need to find the maximum equal suffix sum of the three array.
As we remove element from the top of stack the remaining sum is the suffix sum up to current element. So, if we put all the suffix sums of stack1 and stack2 in an unordered set and traverse the suffix sum array of stack3, and if we find a suffix sum which is present in all three then it is our ans.
- Calculate suffix sum of stack1 and stack2 and insert each element in unorderd_set1 and unordered_set2 respectively.
- Calculate suffix sum of stack 3 and store in vector named as suffix.
- Traverse the suffix vector from i = 0 to i = prefix.size() – 1
- Find an index where the suffix sums of all the three stacks are equal
- If not found return 0
C++
#include <bits/stdc++.h>
using namespace std;
int maxEqualSum( int N1, int N2, int N3, vector< int >& S1,
vector< int >& S2, vector< int >& S3)
{
vector< int > suffix(S3.size() + 1, 0);
int sum1 = 0;
unordered_set< int > st1;
for ( int i = S1.size() - 1; i >= 0; i--) {
sum1 = sum1 + S1[i];
st1.insert(sum1);
}
int sum2 = 0;
unordered_set< int > st2;
for ( int i = S2.size() - 1; i >= 0; i--) {
sum2 = sum2 + S2[i];
st2.insert(sum2);
}
for ( int i = S3.size() - 1; i >= 0; i--) {
suffix[i] = suffix[i + 1] + S3[i];
}
for ( int i = 0; i < suffix.size(); i++) {
if (st1.find(suffix[i]) != st1.end()
&& st2.find(suffix[i]) != st2.end()) {
return suffix[i];
}
}
return 0;
}
int main()
{
vector< int > stack1 = { 3, 2, 1, 1, 1 };
vector< int > stack2 = { 4, 3, 2 };
vector< int > stack3 = { 1, 1, 4, 1 };
cout << maxEqualSum(stack1.size(), stack2.size(),
stack3.size(), stack1, stack2,
stack3)
<< endl;
return 0;
}
|
Java
import java.io.*;
import java.util.HashSet;
public class GFG {
public static int maxEqualSum( int N1, int N2, int N3, int [] S1, int [] S2, int [] S3) {
int [] suffix = new int [N3 + 1 ];
int sum1 = 0 ;
HashSet<Integer> st1 = new HashSet<>();
for ( int i = N1 - 1 ; i >= 0 ; i--) {
sum1 += S1[i];
st1.add(sum1);
}
int sum2 = 0 ;
HashSet<Integer> st2 = new HashSet<>();
for ( int i = N2 - 1 ; i >= 0 ; i--) {
sum2 += S2[i];
st2.add(sum2);
}
for ( int i = N3 - 1 ; i >= 0 ; i--) {
suffix[i] = suffix[i + 1 ] + S3[i];
}
for ( int i = 0 ; i < suffix.length; i++) {
if (st1.contains(suffix[i]) && st2.contains(suffix[i])) {
return suffix[i];
}
}
return 0 ;
}
public static void main(String[] args) {
int [] stack1 = { 3 , 2 , 1 , 1 , 1 };
int [] stack2 = { 4 , 3 , 2 };
int [] stack3 = { 1 , 1 , 4 , 1 };
System.out.println(maxEqualSum(stack1.length, stack2.length, stack3.length, stack1, stack2, stack3));
}
}
|
Python3
def maxEqualSum(N1, N2, N3, S1, S2, S3):
suffix = [ 0 ] * (N3 + 1 )
sum1 = 0
st1 = set ()
for i in range (N1 - 1 , - 1 , - 1 ):
sum1 + = S1[i]
st1.add(sum1)
sum2 = 0
st2 = set ()
for i in range (N2 - 1 , - 1 , - 1 ):
sum2 + = S2[i]
st2.add(sum2)
for i in range (N3 - 1 , - 1 , - 1 ):
suffix[i] = suffix[i + 1 ] + S3[i]
for i in range ( len (suffix)):
if suffix[i] in st1 and suffix[i] in st2:
return suffix[i]
return 0
stack1 = [ 3 , 2 , 1 , 1 , 1 ]
stack2 = [ 4 , 3 , 2 ]
stack3 = [ 1 , 1 , 4 , 1 ]
print (maxEqualSum( len (stack1), len (stack2), len (stack3), stack1, stack2, stack3))
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int MaxEqualSum( int N1, int N2, int N3, List< int > S1,
List< int > S2, List< int > S3)
{
List< int > suffix = new List< int >(S3.Count + 1);
int sum1 = 0;
HashSet< int > st1 = new HashSet< int >();
for ( int i = S1.Count - 1; i >= 0; i--)
{
sum1 = sum1 + S1[i];
st1.Add(sum1);
}
int sum2 = 0;
HashSet< int > st2 = new HashSet< int >();
for ( int i = S2.Count - 1; i >= 0; i--)
{
sum2 = sum2 + S2[i];
st2.Add(sum2);
}
for ( int i = S3.Count - 1; i >= 0; i--)
{
suffix.Insert(0, S3[i] + (suffix.Count > 0 ? suffix[0] : 0));
}
foreach ( int s in suffix)
{
if (st1.Contains(s) && st2.Contains(s))
{
return s;
}
}
return 0;
}
static void Main( string [] args)
{
List< int > stack1 = new List< int > { 3, 2, 1, 1, 1 };
List< int > stack2 = new List< int > { 4, 3, 2 };
List< int > stack3 = new List< int > { 1, 1, 4, 1 };
Console.WriteLine(MaxEqualSum(stack1.Count, stack2.Count,
stack3.Count, stack1, stack2,
stack3));
}
}
|
Javascript
function maxEqualSum(N1, N2, N3, S1, S2, S3) {
let suffix = new Array(S3.length + 1).fill(0);
let sum1 = 0;
let st1 = new Set();
for (let i = S1.length - 1; i >= 0; i--) {
sum1 = sum1 + S1[i];
st1.add(sum1);
}
let sum2 = 0;
let st2 = new Set();
for (let i = S2.length - 1; i >= 0; i--) {
sum2 = sum2 + S2[i];
st2.add(sum2);
}
for (let i = S3.length - 1; i >= 0; i--) {
suffix[i] = suffix[i + 1] + S3[i];
}
for (let i = 0; i < suffix.length; i++) {
if (st1.has(suffix[i]) && st2.has(suffix[i])) {
return suffix[i];
}
}
return 0;
}
let stack1 = [3, 2, 1, 1, 1];
let stack2 = [4, 3, 2];
let stack3 = [1, 1, 4, 1];
console.log(maxEqualSum(stack1.length, stack2.length,
stack3.length, stack1, stack2, stack3));
|
Time Complexity : O(n1+ n2 + n3) where n1, n2 and n3 are sizes of three stacks. As we have different loops for each stack.
Auxiliary space: O(n1+n2+n3) because we are storing the prefix sums
Last Updated :
13 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...