Skip to content
Related Articles

Related Articles

Count of ways to split an Array into three contiguous Subarrays having increasing Sum
  • Difficulty Level : Hard
  • Last Updated : 11 May, 2021

Given an array arr[] consisting of non-negative integers, the task is to find the number of ways to split the array into three non-empty contiguous subarrays such that their respective sum of elements are in increasing order.

Examples:

Input: arr[] = {2, 3, 1, 7} 
Output:
Explanation: 
{{2}, {3, 1}, {7}}, {{2}, {3}, {1, 7}} are the possible splits.
Input: arr[] = {1, 2, 0} 
Output: 0

Approach: The idea is to use the Prefix and Suffix sum array and Two Pointers technique. Follow the steps below to solve the problem:

  • Generate the prefix sum array and suffix sum array.
  • Initialize two pointers s and e to find the sum of the second subarray.
  • Iterate over the array, increment curr_subarray_sum with arr[e] while curr_subarray_sum less than prefix_sum[s – 1] and keep incrementing e.
  • Whenever curr_subarray_sum is ≥ prefix_sum[s – 1], then check if curr_subarray_sum is ≤ suffix_sum[e]. If found to be true, increment count.
  • Reduce curr_subarray_sum by arr[s] and increment s.
  • Repeat the above steps and finally, print count

Below is the implementation of the above approach:

C++




// C++ program to implement
// the above approach
#include<bits/stdc++.h>
using namespace std;
 
// Function to count the number of ways
// to split array into three contigous
// subarrays of the required type
int findCount(int arr[], int n)
{
 
    // Stores the prefix sums
    int prefix_sum[n];
 
    prefix_sum[0] = arr[0];
 
    for(int i = 1; i < n; i++)
        prefix_sum[i] = prefix_sum[i - 1] + arr[i];
 
    // Stores the suffix sums
    int suffix_sum[n];
 
    suffix_sum[n - 1] = arr[n - 1];
 
    for(int i = n - 2; i >= 0; i--)
        suffix_sum[i] = suffix_sum[i + 1] + arr[i];
 
    int s = 1, e = 1;
    int curr_subarray_sum = 0, count = 0;
 
    // Traverse the given array
    while (s < n - 1 && e < n - 1)
    {
         
        // Updating curr_subarray_sum until
        // it is less than prefix_sum[s-1]
        while (e < n - 1 && curr_subarray_sum <
               prefix_sum[s - 1])
        {
            curr_subarray_sum += arr[e++];
        }
 
        if (curr_subarray_sum <= suffix_sum[e])
        {
             
            // Increase count
            count++;
        }
 
        // Decrease curr_subarray_sum by arr[s[]
        curr_subarray_sum -= arr[s++];
    }
 
    // Return count
    return count;
}
 
// Driver code
int32_t main()
{
    int arr[] = { 2, 3, 1, 7 };
    int n = sizeof arr / sizeof arr[0];
     
    cout << (findCount(arr, n));
}
 
// This code is contributed by Stream_Cipher

Java




// Java Program to implement
// the above approach
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to count the number of ways
    // to split array into three contigous
    // subarrays of the required type
    static int findCount(int arr[], int n)
    {
 
        // Stores the prefix sums
        int[] prefix_sum = new int[n];
 
        prefix_sum[0] = arr[0];
 
        for (int i = 1; i < n; i++)
            prefix_sum[i]
                = prefix_sum[i - 1] + arr[i];
 
        // Stores the suffix sums
        int[] suffix_sum = new int[n];
 
        suffix_sum[n - 1] = arr[n - 1];
 
        for (int i = n - 2; i >= 0; i--)
            suffix_sum[i]
                = suffix_sum[i + 1] + arr[i];
 
        int s = 1, e = 1;
        int curr_subarray_sum = 0, count = 0;
 
        // Traverse the given array
        while (s < n - 1 && e < n - 1) {
 
            // Updating curr_subarray_sum until
            // it is less than prefix_sum[s-1]
            while (e < n - 1
                   && curr_subarray_sum
                          < prefix_sum[s - 1]) {
                curr_subarray_sum += arr[e++];
            }
 
            if (curr_subarray_sum <= suffix_sum[e]) {
                // Increase count
                count++;
            }
 
            // Decrease curr_subarray_sum by arr[s[]
            curr_subarray_sum -= arr[s++];
        }
 
        // Return count
        return count;
    }
 
    // Driver Code
    public static void main(String args[])
    {
 
        int[] arr = { 2, 3, 1, 7 };
        int n = arr.length;
        System.out.println(findCount(arr, n));
    }
}

Python3




# Python3 program to implement
# the above approach
 
# Function to count the number of ways
# to split array into three contigous
# subarrays of the required type
def findCount(arr, n):
 
    # Stores the prefix sums
    prefix_sum = [0 for x in range(n)]
    prefix_sum[0] = arr[0]
     
    for i in range(1, n):
        prefix_sum[i] = prefix_sum[i - 1] + arr[i]
     
    # Stores the suffix sums
    suffix_sum = [0 for x in range(n)]
     
    suffix_sum[n - 1] = arr[n - 1]
     
    for i in range(n - 2, -1, -1):
        suffix_sum[i] = suffix_sum[i + 1] + arr[i]
     
    s = 1
    e = 1
    curr_subarray_sum = 0
    count = 0
     
    #Traverse the given array
    while (s < n - 1 and e < n - 1):
         
        # Updating curr_subarray_sum until
        # it is less than prefix_sum[s-1]
        while (e < n - 1 and
               curr_subarray_sum < prefix_sum[s - 1]):
            curr_subarray_sum += arr[e]
            e += 1
                 
        if (curr_subarray_sum <= suffix_sum[e]):
             
            # Increase count
            count += 1
                 
        # Decrease curr_subarray_sum by arr[s[]
        curr_subarray_sum -= arr[s]
        s += 1
     
    # Return count
    return count
     
# Driver code
arr = [ 2, 3, 1, 7 ]
n = len(arr)
 
print(findCount(arr, n))
 
# This code is contributed by Stream_Cipher

C#




// C# Program to implement
// the above approach
using System;
class GFG{
 
  // Function to count the number of ways
  // to split array into three contigous
  // subarrays of the required type
  static int findCount(int []arr, int n)
  {
 
    // Stores the prefix sums
    int[] prefix_sum = new int[n];
 
    prefix_sum[0] = arr[0];
 
    for (int i = 1; i < n; i++)
      prefix_sum[i] = prefix_sum[i - 1] + arr[i];
 
    // Stores the suffix sums
    int[] suffix_sum = new int[n];
 
    suffix_sum[n - 1] = arr[n - 1];
 
    for (int i = n - 2; i >= 0; i--)
      suffix_sum[i] = suffix_sum[i + 1] + arr[i];
 
    int s = 1, e = 1;
    int curr_subarray_sum = 0, count = 0;
 
    // Traverse the given array
    while (s < n - 1 && e < n - 1)
    {
 
      // Updating curr_subarray_sum until
      // it is less than prefix_sum[s-1]
      while (e < n - 1 &&
             curr_subarray_sum < prefix_sum[s - 1])
      {
        curr_subarray_sum += arr[e++];
      }
 
      if (curr_subarray_sum <= suffix_sum[e])
      {
        // Increase count
        count++;
      }
 
      // Decrease curr_subarray_sum by arr[s[]
      curr_subarray_sum -= arr[s++];
    }
 
    // Return count
    return count;
  }
 
  // Driver Code
  public static void Main(String []args)
  {
 
    int[] arr = { 2, 3, 1, 7 };
    int n = arr.Length;
    Console.WriteLine(findCount(arr, n));
  }
}
 
// This code is contributed by Rohit_ranjan

Javascript




<script>
 
// JavaScript program for the above approach
  
   // Function to count the number of ways
    // to split array leto three contigous
    // subarrays of the required type
    function findCount(arr, n)
    {
   
        // Stores the prefix sums
        let prefix_sum = Array.from({length: n},
        (_, i) => 0);
   
        prefix_sum[0] = arr[0];
   
        for (let i = 1; i < n; i++)
            prefix_sum[i]
                = prefix_sum[i - 1] + arr[i];
   
        // Stores the suffix sums
        let suffix_sum = Array.from({length: n},
        (_, i) => 0);
   
        suffix_sum[n - 1] = arr[n - 1];
   
        for (let i = n - 2; i >= 0; i--)
            suffix_sum[i]
                = suffix_sum[i + 1] + arr[i];
   
        let s = 1, e = 1;
        let curr_subarray_sum = 0, count = 0;
   
        // Traverse the given array
        while (s < n - 1 && e < n - 1) {
   
            // Updating curr_subarray_sum until
            // it is less than prefix_sum[s-1]
            while (e < n - 1
                   && curr_subarray_sum
                          < prefix_sum[s - 1]) {
                curr_subarray_sum += arr[e++];
            }
   
            if (curr_subarray_sum <= suffix_sum[e]) {
                // Increase count
                count++;
            }
   
            // Decrease curr_subarray_sum by arr[s[]
            curr_subarray_sum -= arr[s++];
        }
   
        // Return count
        return count;
    }
     
// Driver Code
     
        let arr = [ 2, 3, 1, 7 ];
        let n = arr.length;
        document.write(findCount(arr, n));
      
</script>
Output: 
2

 

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

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.




My Personal Notes arrow_drop_up
Recommended Articles
Page :