给定一个由非负整数组成的数组arr[] ,任务是找到将数组拆分为三个非空连续子数组的方法数,以便它们各自的元素总和按递增顺序排列。
例子:
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
方法:想法是使用前缀和后缀和数组和两个指针技术。请按照以下步骤解决问题:
- 生成前缀和数组和后缀和数组。
- 初始化两个指针s和e以找到第二个子数组的和。
- 迭代数组,使用arr[e]增加curr_subarray_sum而curr_subarray_sum小于prefix_sum[s – 1]并继续增加e 。
- 每当curr_subarray_sum ≥ prefix_sum[s – 1] ,然后检查curr_subarray_sum是否≤ suffix_sum[e] 。如果发现为真,则增加count 。
- 将curr_subarray_sum减少arr[s]并增加s 。
- 重复以上步骤,最后打印计数
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
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
输出:
2
时间复杂度: O(N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live