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