Print indices of pair of array elements required to be removed to split array into 3 equal sum subarrays
Last Updated :
24 Mar, 2022
Given an array arr[] consisting of N integers, the task is to print the indices of two array elements required to be removed such that the given array can be split into three subarrays of equal sum. If not possible to do so, then print “-1”.
Examples:
Input: arr[] = {2, 5, 12, 7, 19, 4, 3}
Output: 2 4
Explanation:
Removing arr[2] and arr[4] modifies arr[] to {2, 5, 7, 4, 3}.
Sum of subarray {arr[0], arr[1]} = 7.
arr[2] = 7.
Sum of subarray {arr[3], arr[4]} = 7.
Input: arr[] = {2, 1, 13, 5, 14}
Output: -1
Naive Approach: The simplest approach is to generate all possible pairs of array elements and for each pair, check if removal of these pairs can generate three equal sum subarrays from the given array.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findSplit( int arr[], int N)
{
for ( int l = 1; l <= N - 4; l++) {
for ( int r = l + 2; r <= N - 2; r++) {
int lsum = 0, rsum = 0, msum = 0;
for ( int i = 0; i <= l - 1; i++) {
lsum += arr[i];
}
for ( int i = l + 1; i <= r - 1; i++) {
msum += arr[i];
}
for ( int i = r + 1; i < N; i++) {
rsum += arr[i];
}
if (lsum == rsum && rsum == msum) {
cout << l << " " << r << endl;
return ;
}
}
}
cout << -1 << endl;
}
int main()
{
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
int N = sizeof (arr) / sizeof (arr[0]);
findSplit(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void findSplit( int arr[], int N)
{
for ( int l = 1 ; l <= N - 4 ; l++)
{
for ( int r = l + 2 ; r <= N - 2 ; r++)
{
int lsum = 0 , rsum = 0 , msum = 0 ;
for ( int i = 0 ; i <= l - 1 ; i++) {
lsum += arr[i];
}
for ( int i = l + 1 ; i <= r - 1 ; i++) {
msum += arr[i];
}
for ( int i = r + 1 ; i < N; i++) {
rsum += arr[i];
}
if (lsum == rsum && rsum == msum) {
System.out.println( l + " " + r );
return ;
}
}
}
System.out.print(- 1 );
}
public static void main(String[] args)
{
int arr[] = { 2 , 5 , 12 , 7 , 19 , 4 , 3 };
int N = arr.length;
findSplit(arr, N);
}
}
|
Python3
def findSplit(arr, N):
for l in range ( 1 , N - 3 , 1 ):
for r in range (l + 2 , N - 1 , 1 ):
lsum = 0
rsum = 0
msum = 0
for i in range ( 0 , l, 1 ):
lsum + = arr[i]
for i in range (l + 1 , r, 1 ):
msum + = arr[i]
for i in range (r + 1 , N, 1 ):
rsum + = arr[i]
if (lsum = = rsum and rsum = = msum):
print (l, r)
return
print ( - 1 )
if __name__ = = '__main__' :
arr = [ 2 , 5 , 12 , 7 , 19 , 4 , 3 ]
N = len (arr)
findSplit(arr, N)
|
C#
using System;
class GFG
{
static void findSplit( int []arr, int N)
{
for ( int l = 1; l <= N - 4; l++)
{
for ( int r = l + 2; r <= N - 2; r++)
{
int lsum = 0, rsum = 0, msum = 0;
for ( int i = 0; i <= l - 1; i++) {
lsum += arr[i];
}
for ( int i = l + 1; i <= r - 1; i++) {
msum += arr[i];
}
for ( int i = r + 1; i < N; i++) {
rsum += arr[i];
}
if (lsum == rsum && rsum == msum) {
Console.WriteLine( l + " " + r );
return ;
}
}
}
Console.Write(-1 );
}
public static void Main( string [] args)
{
int []arr = { 2, 5, 12, 7, 19, 4, 3 };
int N = arr.Length;
findSplit(arr, N);
}
}
|
Javascript
<script>
function findSplit(arr, N)
{
for (let l = 1; l <= N - 4; l++)
{
for (let r = l + 2; r <= N - 2; r++)
{
let lsum = 0, rsum = 0, msum = 0;
for (let i = 0; i <= l - 1; i++) {
lsum += arr[i];
}
for (let i = l + 1; i <= r - 1; i++) {
msum += arr[i];
}
for (let i = r + 1; i < N; i++) {
rsum += arr[i];
}
if (lsum == rsum && rsum == msum) {
document.write( l + " " + r + "</br>" );
return ;
}
}
}
document.write(-1 );
}
let arr = [ 2, 5, 12, 7, 19, 4, 3 ];
let N = arr.length;
findSplit(arr, N);
</script>
|
Time Complexity: O(N3)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to use Prefix Sum array technique to find all subarray sums in constant time. Follow the steps below to solve the problem:
- Initialize a vector sum of size N to store the prefix sum of the array.
- Initialize two variables, say l & r, to store the two indexes which are to be dropped in order to split the array into 3 equal sum subarrays.
- Sum of the three subarrays would be sum[l – 1], sum[r – 1] – sum[l] and sum[N – 1] – sum[r].
- Iterate over the range [1, N – 4] using a variable l:
- Iterate over the range [l + 2, N – 2] using variable r and check if at any point, left subarray sum is equal to middle subarray sum and right subarray sum, then print the values of l & r and return.
- If no such pair exists, print -1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findSplit( int arr[], int N)
{
vector< int > sum(N);
for ( int i = 0; i < N; i++) {
sum[i] = arr[i];
}
for ( int i = 1; i < N; i++) {
sum[i] += sum[i - 1];
}
for ( int l = 1; l <= N - 4; l++) {
for ( int r = l + 2; r <= N - 2; r++) {
int lsum = 0, rsum = 0, msum = 0;
lsum = sum[l - 1];
msum = sum[r - 1] - sum[l];
rsum = sum[N - 1] - sum[r];
if (lsum == rsum && rsum == msum) {
cout << l << " " << r << endl;
return ;
}
}
}
cout << -1 << endl;
}
int main()
{
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
int N = sizeof (arr) / sizeof (arr[0]);
findSplit(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void findSplit( int arr[], int N)
{
int []sum = new int [N];
for ( int i = 0 ; i < N; i++)
{
sum[i] = arr[i];
}
for ( int i = 1 ; i < N; i++)
{
sum[i] += sum[i - 1 ];
}
for ( int l = 1 ; l <= N - 4 ; l++) {
for ( int r = l + 2 ; r <= N - 2 ; r++) {
int lsum = 0 , rsum = 0 , msum = 0 ;
lsum = sum[l - 1 ];
msum = sum[r - 1 ] - sum[l];
rsum = sum[N - 1 ] - sum[r];
if (lsum == rsum && rsum == msum) {
System.out.print(l+ " " + r + "\n" );
return ;
}
}
}
System.out.print(- 1 + "\n" );
}
public static void main(String[] args)
{
int arr[] = { 2 , 5 , 12 , 7 , 19 , 4 , 3 };
int N = arr.length;
findSplit(arr, N);
}
}
|
Python3
def findSplit(arr, N):
sum = [i for i in arr]
for i in range ( 1 , N):
sum [i] + = sum [i - 1 ]
for l in range ( 1 , N - 3 ):
for r in range (l + 2 , N - 1 ):
lsum , rsum , msum = 0 , 0 , 0
lsum = sum [l - 1 ]
msum = sum [r - 1 ] - sum [l]
rsum = sum [N - 1 ] - sum [r]
if (lsum = = rsum and rsum = = msum):
print (l, r)
return
print ( - 1 )
if __name__ = = '__main__' :
arr = [ 2 , 5 , 12 , 7 , 19 , 4 , 3 ]
N = len (arr)
findSplit(arr, N)
|
C#
using System;
public class GFG
{
static void findSplit( int []arr, int N)
{
int []sum = new int [N];
for ( int i = 0; i < N; i++)
{
sum[i] = arr[i];
}
for ( int i = 1; i < N; i++)
{
sum[i] += sum[i - 1];
}
for ( int l = 1; l <= N - 4; l++) {
for ( int r = l + 2; r <= N - 2; r++) {
int lsum = 0, rsum = 0, msum = 0;
lsum = sum[l - 1];
msum = sum[r - 1] - sum[l];
rsum = sum[N - 1] - sum[r];
if (lsum == rsum && rsum == msum) {
Console.Write(l+ " " + r + "\n" );
return ;
}
}
}
Console.Write(-1 + "\n" );
}
public static void Main(String[] args)
{
int []arr = { 2, 5, 12, 7, 19, 4, 3 };
int N = arr.Length;
findSplit(arr, N);
}
}
|
Javascript
<script>
function findSplit(arr, N)
{
let sum = new Array(N);
for (let i = 0; i < N; i++)
{
sum[i] = arr[i];
}
for (let i = 1; i < N; i++)
{
sum[i] += sum[i - 1];
}
for (let l = 1; l <= N - 4; l++) {
for (let r = l + 2; r <= N - 2; r++) {
let lsum = 0, rsum = 0, msum = 0;
lsum = sum[l - 1];
msum = sum[r - 1] - sum[l];
rsum = sum[N - 1] - sum[r];
if (lsum == rsum && rsum == msum) {
document.write(l+ " " + r + "</br>" );
return ;
}
}
}
document.write(-1 + "</br>" );
}
let arr = [ 2, 5, 12, 7, 19, 4, 3 ];
let N = arr.length;
findSplit(arr, N);
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(N)
Most Optimal Approach: The most optimal idea is to make use of the two-pointer technique along with the use of Prefix Sum. Follow the steps below to solve the problem:
- Initialize a vector of size N to store the prefix sum of the array.
- Initialize two variables, say l & r, to traverse the array using the two-pointer approach.
- Traverse the array till l < r or until either all three sums become equal:
- If the sum of the left subarray is greater than the sum of the right subarray, add an extra element to the right subarray. Therefore, reducing the value of r by 1.
- If the sum of the right subarray is greater than the sum of the left subarray, add an element to the left subarray. Therefore, increasing l by 1.
- If both the sum of left and right subarrays are equal, but not equal to the sum of the middle subarray increase l by 1 and reduce r by 1.
- If no such pair exists, print -1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findSplit( int arr[], int N)
{
int l = 1, r = N - 2;
int lsum, msum, rsum;
vector< int > sum(N);
sum[0] = arr[0];
for ( int i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
while (l < r) {
lsum = sum[l - 1];
msum = sum[r - 1] - sum[l];
rsum = sum[N - 1] - sum[r];
if (lsum == msum and msum == rsum) {
cout << l << " " << r << endl;
return ;
}
if (lsum < rsum)
l++;
else if (lsum > rsum)
r--;
else {
l++;
r--;
}
}
cout << -1 << endl;
}
int main()
{
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
int N = sizeof (arr) / sizeof (arr[0]);
findSplit(arr, N);
return 0;
}
|
Java
public class GFG
{
static void findSplit( int []arr, int N)
{
int l = 1 , r = N - 2 ;
int lsum, msum, rsum;
int sum[] = new int [N];
sum[ 0 ] = arr[ 0 ];
for ( int i = 1 ; i < N; i++) {
sum[i] = sum[i - 1 ] + arr[i];
}
while (l < r) {
lsum = sum[l - 1 ];
msum = sum[r - 1 ] - sum[l];
rsum = sum[N - 1 ] - sum[r];
if (lsum == msum && msum == rsum) {
System.out.println(l + " " + r);
return ;
}
if (lsum < rsum)
l++;
else if (lsum > rsum)
r--;
else {
l++;
r--;
}
}
System.out.println(- 1 );
}
public static void main (String[] args)
{
int []arr = { 2 , 5 , 12 , 7 , 19 , 4 , 3 };
int N = arr.length;
findSplit(arr, N);
}
}
|
Python3
def findSplit(arr, N) :
l = 1 ; r = N - 2 ;
sum = [ 0 ] * N;
sum [ 0 ] = arr[ 0 ];
for i in range ( 1 , N) :
sum [i] = sum [i - 1 ] + arr[i];
while (l < r) :
lsum = sum [l - 1 ];
msum = sum [r - 1 ] - sum [l];
rsum = sum [N - 1 ] - sum [r];
if (lsum = = msum and msum = = rsum) :
print (l,r);
return ;
if (lsum < rsum) :
l + = 1 ;
elif (lsum > rsum) :
r - = 1 ;
else :
l + = 1 ;
r - = 1 ;
print ( - 1 );
if __name__ = = "__main__" :
arr = [ 2 , 5 , 12 , 7 , 19 , 4 , 3 ];
N = len (arr);
findSplit(arr, N);
|
C#
using System;
class GFG {
static void findSplit( int [] arr, int N)
{
int l = 1, r = N - 2;
int lsum, msum, rsum;
int [] sum = new int [N];
sum[0] = arr[0];
for ( int i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
while (l < r) {
lsum = sum[l - 1];
msum = sum[r - 1] - sum[l];
rsum = sum[N - 1] - sum[r];
if (lsum == msum && msum == rsum) {
Console.Write(l + " " + r);
return ;
}
if (lsum < rsum)
l++;
else if (lsum > rsum)
r--;
else {
l++;
r--;
}
}
Console.Write(-1);
}
static void Main()
{
int [] arr = { 2, 5, 12, 7, 19, 4, 3 };
int N = arr.Length;
findSplit(arr, N);
}
}
|
Javascript
<script>
function findSplit(arr, N)
{
let l = 1, r = N - 2;
let lsum, msum, rsum;
let sum = new Array(N);
sum[0] = arr[0];
for (let i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
while (l < r) {
lsum = sum[l - 1];
msum = sum[r - 1] - sum[l];
rsum = sum[N - 1] - sum[r];
if (lsum == msum && msum == rsum) {
document.write(l + " " + r);
return ;
}
if (lsum < rsum)
l++;
else if (lsum > rsum)
r--;
else {
l++;
r--;
}
}
document.write(-1);
}
let arr = [ 2, 5, 12, 7, 19, 4, 3 ];
let N = arr.length;
findSplit(arr, N);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...