Open In App

Print indices of pair of array elements required to be removed to split array into 3 equal sum subarrays

Improve
Improve
Like Article
Like
Save
Share
Report

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++




// 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




// 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.


Python3




# 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#




// 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


Javascript




<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>


Output: 

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++




// 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




// 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




# 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#




// 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


Javascript




<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>


Output: 

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++




// 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




// 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




# 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#




// 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.


Javascript




<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>


Output: 

2 4

 

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



Last Updated : 24 Mar, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads