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: 2
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 contiguous // 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 contiguous // 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 contiguous # 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 contiguous // 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 into three contiguous // 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> |
2
Time Complexity: O(N)
Auxiliary Space: O(N)