Count of ways to split an Array into three contiguous Subarrays having increasing Sum

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:



Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

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

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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));
    }
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

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

filter_none

edit
close

play_arrow

link
brightness_4
code

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

Output: 
2

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : Rohit_ranjan, Stream_Cipher

Article Tags :