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++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to check if array can // be split into three equal sum // subarrays by removing two elements void findSplit( int arr[], int N)
{ for ( int l = 1; l <= N - 4; l++) {
for ( int r = l + 2; r <= N - 2; r++) {
// Stores sum of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
for ( int i = 0; i <= l - 1; i++) {
lsum += arr[i];
}
// Sum of middle subarray
for ( int i = l + 1; i <= r - 1; i++) {
msum += arr[i];
}
// Sum of right subarray
for ( int i = r + 1; i < N; i++) {
rsum += arr[i];
}
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
cout << l << " " << r << endl;
return ;
}
}
}
// If no pair exists, print -1
cout << -1 << endl;
} // Driver code int main()
{ // Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = sizeof (arr) / sizeof (arr[0]);
findSplit(arr, N);
return 0;
} |
// Java program for the above approach import java.util.*;
class GFG
{ // Function to check if array can // be split into three equal sum // subarrays by removing two elements static void findSplit( int arr[], int N)
{ for ( int l = 1 ; l <= N - 4 ; l++)
{
for ( int r = l + 2 ; r <= N - 2 ; r++)
{
// Stores sum of all three subarrays
int lsum = 0 , rsum = 0 , msum = 0 ;
// Sum of left subarray
for ( int i = 0 ; i <= l - 1 ; i++) {
lsum += arr[i];
}
// Sum of middle subarray
for ( int i = l + 1 ; i <= r - 1 ; i++) {
msum += arr[i];
}
// Sum of right subarray
for ( int i = r + 1 ; i < N; i++) {
rsum += arr[i];
}
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
System.out.println( l + " " + r );
return ;
}
}
}
// If no pair exists, print -1
System.out.print(- 1 );
} // Driver Code public static void main(String[] args)
{ // Given array
int arr[] = { 2 , 5 , 12 , 7 , 19 , 4 , 3 };
// Size of the array
int N = arr.length;
findSplit(arr, N);
} } // This code is contributed by sanjoy_62. |
# Python 3 program for the above approach # Function to check if array can # be split into three equal sum # subarrays by removing two elements def findSplit(arr, N):
for l in range ( 1 , N - 3 , 1 ):
for r in range (l + 2 , N - 1 , 1 ):
# Stores sum of all three subarrays
lsum = 0
rsum = 0
msum = 0
# Sum of left subarray
for i in range ( 0 , l, 1 ):
lsum + = arr[i]
# Sum of middle subarray
for i in range (l + 1 , r, 1 ):
msum + = arr[i]
# Sum of right subarray
for i in range (r + 1 , N, 1 ):
rsum + = arr[i]
# Check if sum of subarrays are equal
if (lsum = = rsum and rsum = = msum):
# Print the possible pair
print (l, r)
return
# If no pair exists, print -1
print ( - 1 )
# Driver code if __name__ = = '__main__' :
# Given array
arr = [ 2 , 5 , 12 , 7 , 19 , 4 , 3 ]
# Size of the array
N = len (arr)
findSplit(arr, N)
# This code is contributed by SURENDRA_GANGWAR.
|
// C# program for the above approach using System;
class GFG
{ // Function to check if array can
// be split into three equal sum
// subarrays by removing two elements
static void findSplit( int []arr, int N)
{
for ( int l = 1; l <= N - 4; l++)
{
for ( int r = l + 2; r <= N - 2; r++)
{
// Stores sum of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
for ( int i = 0; i <= l - 1; i++) {
lsum += arr[i];
}
// Sum of middle subarray
for ( int i = l + 1; i <= r - 1; i++) {
msum += arr[i];
}
// Sum of right subarray
for ( int i = r + 1; i < N; i++) {
rsum += arr[i];
}
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
Console.WriteLine( l + " " + r );
return ;
}
}
}
// If no pair exists, print -1
Console.Write(-1 );
}
// Driver Code
public static void Main( string [] args)
{
// Given array
int []arr = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.Length;
findSplit(arr, N);
}
} // This code is contributed by AnkThon |
<script> // JavaScript program for the above approach
// Function to check if array can
// be split into three equal sum
// subarrays by removing two elements
function findSplit(arr, N)
{
for (let l = 1; l <= N - 4; l++)
{
for (let r = l + 2; r <= N - 2; r++)
{
// Stores sum of all three subarrays
let lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
for (let i = 0; i <= l - 1; i++) {
lsum += arr[i];
}
// Sum of middle subarray
for (let i = l + 1; i <= r - 1; i++) {
msum += arr[i];
}
// Sum of right subarray
for (let i = r + 1; i < N; i++) {
rsum += arr[i];
}
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
document.write( l + " " + r + "</br>" );
return ;
}
}
}
// If no pair exists, print -1
document.write(-1 );
}
// Given array
let arr = [ 2, 5, 12, 7, 19, 4, 3 ];
// Size of the array
let N = arr.length;
findSplit(arr, N);
</script> |
2 4
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++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to check if array can // be split into three equal sum // subarrays by removing a pair void findSplit( int arr[], int N)
{ // Stores prefix sum array
vector< int > sum(N);
// Copy array elements
for ( int i = 0; i < N; i++) {
sum[i] = arr[i];
}
// Traverse the array
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++) {
// Stores sums of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
cout << l << " " << r << endl;
return ;
}
}
}
// If no such pair exists, print -1
cout << -1 << endl;
} // Driver Code int main()
{ // Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = sizeof (arr) / sizeof (arr[0]);
findSplit(arr, N);
return 0;
} |
// Java program for the above approach import java.util.*;
class GFG
{ // Function to check if array can // be split into three equal sum // subarrays by removing a pair static void findSplit( int arr[], int N)
{ // Stores prefix sum array
int []sum = new int [N];
// Copy array elements
for ( int i = 0 ; i < N; i++)
{
sum[i] = arr[i];
}
// Traverse the array
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++) {
// Stores sums of all three subarrays
int lsum = 0 , rsum = 0 , msum = 0 ;
// Sum of left subarray
lsum = sum[l - 1 ];
// Sum of middle subarray
msum = sum[r - 1 ] - sum[l];
// Sum of right subarray
rsum = sum[N - 1 ] - sum[r];
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
System.out.print(l+ " " + r + "\n" );
return ;
}
}
}
// If no such pair exists, print -1
System.out.print(- 1 + "\n" );
} // Driver Code public static void main(String[] args)
{ // Given array
int arr[] = { 2 , 5 , 12 , 7 , 19 , 4 , 3 };
// Size of the array
int N = arr.length;
findSplit(arr, N);
} } // This code is contributed by shikhasingrajput |
# Python3 program for the above approach # Function to check if array can # be split into three equal sum # subarrays by removing a pair def findSplit(arr, N):
# Stores prefix sum array
sum = [i for i in arr]
# Traverse the array
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 ):
# Stores sums of all three subarrays
lsum , rsum , msum = 0 , 0 , 0
# Sum of left subarray
lsum = sum [l - 1 ]
# Sum of middle subarray
msum = sum [r - 1 ] - sum [l]
# Sum of right subarray
rsum = sum [N - 1 ] - sum [r]
# Check if sum of subarrays are equal
if (lsum = = rsum and rsum = = msum):
# Print possible pair
print (l, r)
return
# If no such pair exists, print -1
print ( - 1 )
# Driver Code if __name__ = = '__main__' :
# Given array
arr = [ 2 , 5 , 12 , 7 , 19 , 4 , 3 ]
# Size of the array
N = len (arr)
findSplit(arr, N)
# This code is contributed by mohit kumar 29. |
// C# program for the above approach using System;
public class GFG
{ // Function to check if array can // be split into three equal sum // subarrays by removing a pair static void findSplit( int []arr, int N)
{ // Stores prefix sum array
int []sum = new int [N];
// Copy array elements
for ( int i = 0; i < N; i++)
{
sum[i] = arr[i];
}
// Traverse the array
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++) {
// Stores sums of all three subarrays
int lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
Console.Write(l+ " " + r + "\n" );
return ;
}
}
}
// If no such pair exists, print -1
Console.Write(-1 + "\n" );
} // Driver Code public static void Main(String[] args)
{ // Given array
int []arr = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.Length;
findSplit(arr, N);
} } // This code is contributed by 29AjayKumar |
<script> // JavaScript program for the above approach
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
function findSplit(arr, N)
{
// Stores prefix sum array
let sum = new Array(N);
// Copy array elements
for (let i = 0; i < N; i++)
{
sum[i] = arr[i];
}
// Traverse the array
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++) {
// Stores sums of all three subarrays
let lsum = 0, rsum = 0, msum = 0;
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Check if sum of subarrays are equal
if (lsum == rsum && rsum == msum) {
// Print the possible pair
document.write(l+ " " + r + "</br>" );
return ;
}
}
}
// If no such pair exists, print -1
document.write(-1 + "</br>" );
}
// Given array
let arr = [ 2, 5, 12, 7, 19, 4, 3 ];
// Size of the array
let N = arr.length;
findSplit(arr, N);
</script> |
2 4
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++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to check if array can // be split into three equal sum // subarrays by removing a pair void findSplit( int arr[], int N)
{ // Two pointers l and r
int l = 1, r = N - 2;
int lsum, msum, rsum;
// Stores prefix sum array
vector< int > sum(N);
sum[0] = arr[0];
// Traverse the array
for ( int i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
// Two pointer approach
while (l < r) {
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Print split indices if sum is equal
if (lsum == msum and msum == rsum) {
cout << l << " " << r << endl;
return ;
}
// Move left pointer if lsum < rsum
if (lsum < rsum)
l++;
// Move right pointer if rsum > lsum
else if (lsum > rsum)
r--;
// Move both pointers if lsum = rsum
// but they are not equal to msum
else {
l++;
r--;
}
}
// If no possible pair exists, print -1
cout << -1 << endl;
} // Driver Code int main()
{ // Given array
int arr[] = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = sizeof (arr) / sizeof (arr[0]);
findSplit(arr, N);
return 0;
} |
// Java program for the above approach public class GFG
{ // Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
static void findSplit( int []arr, int N)
{
// Two pointers l and r
int l = 1 , r = N - 2 ;
int lsum, msum, rsum;
// Stores prefix sum array
int sum[] = new int [N];
sum[ 0 ] = arr[ 0 ];
// Traverse the array
for ( int i = 1 ; i < N; i++) {
sum[i] = sum[i - 1 ] + arr[i];
}
// Two pointer approach
while (l < r) {
// Sum of left subarray
lsum = sum[l - 1 ];
// Sum of middle subarray
msum = sum[r - 1 ] - sum[l];
// Sum of right subarray
rsum = sum[N - 1 ] - sum[r];
// Print split indices if sum is equal
if (lsum == msum && msum == rsum) {
System.out.println(l + " " + r);
return ;
}
// Move left pointer if lsum < rsum
if (lsum < rsum)
l++;
// Move right pointer if rsum > lsum
else if (lsum > rsum)
r--;
// Move both pointers if lsum = rsum
// but they are not equal to msum
else {
l++;
r--;
}
}
// If no possible pair exists, print -1
System.out.println(- 1 );
}
// Driver Code
public static void main (String[] args)
{
// Given array
int []arr = { 2 , 5 , 12 , 7 , 19 , 4 , 3 };
// Size of the array
int N = arr.length;
findSplit(arr, N);
}
} // This code is contributed by AnkThon |
# Python3 program for the above approach # Function to check if array can # be split into three equal sum # subarrays by removing a pair def findSplit(arr, N) :
# Two pointers l and r
l = 1 ; r = N - 2 ;
# Stores prefix sum array
sum = [ 0 ] * N;
sum [ 0 ] = arr[ 0 ];
# Traverse the array
for i in range ( 1 , N) :
sum [i] = sum [i - 1 ] + arr[i];
# Two pointer approach
while (l < r) :
# Sum of left subarray
lsum = sum [l - 1 ];
# Sum of middle subarray
msum = sum [r - 1 ] - sum [l];
# Sum of right subarray
rsum = sum [N - 1 ] - sum [r];
# Print split indices if sum is equal
if (lsum = = msum and msum = = rsum) :
print (l,r);
return ;
# Move left pointer if lsum < rsum
if (lsum < rsum) :
l + = 1 ;
# Move right pointer if rsum > lsum
elif (lsum > rsum) :
r - = 1 ;
# Move both pointers if lsum = rsum
# but they are not equal to msum
else :
l + = 1 ;
r - = 1 ;
# If no possible pair exists, print -1
print ( - 1 );
# Driver Code if __name__ = = "__main__" :
# Given array
arr = [ 2 , 5 , 12 , 7 , 19 , 4 , 3 ];
# Size of the array
N = len (arr);
findSplit(arr, N);
# This code is contributed by AnkThon
|
// C# program for the above approach using System;
class GFG {
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
static void findSplit( int [] arr, int N)
{
// Two pointers l and r
int l = 1, r = N - 2;
int lsum, msum, rsum;
// Stores prefix sum array
int [] sum = new int [N];
sum[0] = arr[0];
// Traverse the array
for ( int i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
// Two pointer approach
while (l < r) {
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Print split indices if sum is equal
if (lsum == msum && msum == rsum) {
Console.Write(l + " " + r);
return ;
}
// Move left pointer if lsum < rsum
if (lsum < rsum)
l++;
// Move right pointer if rsum > lsum
else if (lsum > rsum)
r--;
// Move both pointers if lsum = rsum
// but they are not equal to msum
else {
l++;
r--;
}
}
// If no possible pair exists, print -1
Console.Write(-1);
}
static void Main()
{
// Given array
int [] arr = { 2, 5, 12, 7, 19, 4, 3 };
// Size of the array
int N = arr.Length;
findSplit(arr, N);
}
} // This code is contributed by rameshtravel07. |
<script> // JavaScript program for the above approach
// Function to check if array can
// be split into three equal sum
// subarrays by removing a pair
function findSplit(arr, N)
{
// Two pointers l and r
let l = 1, r = N - 2;
let lsum, msum, rsum;
// Stores prefix sum array
let sum = new Array(N);
sum[0] = arr[0];
// Traverse the array
for (let i = 1; i < N; i++) {
sum[i] = sum[i - 1] + arr[i];
}
// Two pointer approach
while (l < r) {
// Sum of left subarray
lsum = sum[l - 1];
// Sum of middle subarray
msum = sum[r - 1] - sum[l];
// Sum of right subarray
rsum = sum[N - 1] - sum[r];
// Print split indices if sum is equal
if (lsum == msum && msum == rsum) {
document.write(l + " " + r);
return ;
}
// Move left pointer if lsum < rsum
if (lsum < rsum)
l++;
// Move right pointer if rsum > lsum
else if (lsum > rsum)
r--;
// Move both pointers if lsum = rsum
// but they are not equal to msum
else {
l++;
r--;
}
}
// If no possible pair exists, print -1
document.write(-1);
}
// Given array
let arr = [ 2, 5, 12, 7, 19, 4, 3 ];
// Size of the array
let N = arr.length;
findSplit(arr, N);
</script> |
2 4
Time Complexity: O(N)
Auxiliary Space: O(N)