给定大小为N的数组arr [] ,任务是查找可以重复将该数组划分为两个子数组的次数,以使两个子数组的元素之和相同。
例子:
Input: arr[] = { 2, 2, 2, 2 }
Output: 3
Explanation:
1. Make the first partition after index 1. Remaining arrays are {2, 2} on the right side and left side both.
2. Consider the left subarray {2, 2}. Make a partition after index 0 of this left subarray.
Now two similar subarrays with one element each i.e. {2} are formed which cannot be sub-divided.
3. Consider the right subarray {2, 2}. Make a partition after index 0 of this left subarray.
Now two similar subarrays with one element each i.e. {2} are formed which cannot be sub-divided.
Hence the output is 3 as the array was partitioned 3 times.
Input: arr[] = {12, 3, 3, 0, 3, 3}
Output: 4
Explanation:
1. The first partition is after index 0. Remaining array is arr[] = {3, 3, 0, 3, 3}.
2. The second partition is after index 1. The remaining array is {3, 3}, and {0, 3, 3}.
3. The third partition is after index 0 in array {3, 3}.
4. The fourth partition is after 1 in the array {0, 3, 3}
The remaining array is {0, 3}, and {3} which cannot be sub-divided.
Hence the output is 4.
方法:想法是使用递归。步骤如下:
- 找到给定数组arr []的前缀和,并将其存储在数组pref []中。
- 从开始位置迭代到结束位置。
- 对于每个可能的分区索引(例如K ),如果prefix_sum [K] – prefix_sum [start-1] = prefix_sum [end] – prefix_sum [k],则该分区有效。
- 如果在上述步骤中分区有效,则分别处理左右两个子阵列,并确定这两个子阵列是否形成有效的分区。
- 对左右分区重复步骤3和4,直到无法再进行任何分区。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Recursion Function to calculate the
// possible splitting
int splitArray(int start, int end,
int* arr,
int* prefix_sum)
{
// If there are less than
// two elements, we cannot
// partition the sub-array.
if (start >= end)
return 0;
// Iterate from the start
// to end-1.
for (int k = start; k < end; ++k) {
if ((prefix_sum[k] - prefix_sum[start - 1])
== (prefix_sum[end] - prefix_sum[k])) {
// Recursive call to the left
// and the right sub-array.
return 1 + splitArray(start,
k,
arr,
prefix_sum)
+ splitArray(k + 1,
end,
arr,
prefix_sum);
}
}
// If there is no such partition,
// then return 0
return 0;
}
// Function to find the total splitting
void solve(int arr[], int n)
{
// Prefix array to store
// the prefix-sum using
// 1 based indexing
int prefix_sum[n + 1];
prefix_sum[0] = 0;
// Store the prefix-sum
for (int i = 1; i <= n; ++i) {
prefix_sum[i] = prefix_sum[i - 1]
+ arr[i - 1];
}
// Function Call to count the
// number of splitting
cout << splitArray(1, n,
arr,
prefix_sum);
}
// Driver Code
int main()
{
// Given array
int arr[] = { 12, 3, 3, 0, 3, 3 };
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
solve(arr, N);
return 0;
}
Java
// Java program for the above approach
class GFG{
// Recursion Function to calculate the
// possible splitting
static int splitArray(int start, int end,
int[] arr,
int[] prefix_sum)
{
// If there are less than
// two elements, we cannot
// partition the sub-array.
if (start >= end)
return 0;
// Iterate from the start
// to end-1.
for (int k = start; k < end; ++k)
{
if ((prefix_sum[k] - prefix_sum[start - 1]) ==
(prefix_sum[end] - prefix_sum[k]))
{
// Recursive call to the left
// and the right sub-array.
return 1 + splitArray(start, k, arr, prefix_sum) +
splitArray(k + 1, end, arr, prefix_sum);
}
}
// If there is no such partition,
// then return 0
return 0;
}
// Function to find the total splitting
static void solve(int arr[], int n)
{
// Prefix array to store
// the prefix-sum using
// 1 based indexing
int []prefix_sum = new int[n + 1];
prefix_sum[0] = 0;
// Store the prefix-sum
for (int i = 1; i <= n; ++i)
{
prefix_sum[i] = prefix_sum[i - 1] +
arr[i - 1];
}
// Function Call to count the
// number of splitting
System.out.print(splitArray(1, n, arr,
prefix_sum));
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 12, 3, 3, 0, 3, 3 };
int N = arr.length;
// Function call
solve(arr, N);
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 program for the above approach
# Recursion Function to calculate the
# possible splitting
def splitArray(start, end, arr, prefix_sum):
# If there are less than
# two elements, we cannot
# partition the sub-array.
if (start >= end):
return 0
# Iterate from the start
# to end-1.
for k in range(start, end):
if ((prefix_sum[k] - prefix_sum[start - 1]) ==
(prefix_sum[end] - prefix_sum[k])) :
# Recursive call to the left
# and the right sub-array.
return (1 + splitArray(start, k, arr,
prefix_sum) +
splitArray(k + 1, end, arr,
prefix_sum))
# If there is no such partition,
# then return 0
return 0
# Function to find the total splitting
def solve(arr, n):
# Prefix array to store
# the prefix-sum using
# 1 based indexing
prefix_sum = [0] * (n + 1)
prefix_sum[0] = 0
# Store the prefix-sum
for i in range(1, n + 1):
prefix_sum[i] = (prefix_sum[i - 1] +
arr[i - 1])
# Function Call to count the
# number of splitting
print(splitArray(1, n, arr, prefix_sum))
# Driver Code
# Given array
arr = [ 12, 3, 3, 0, 3, 3 ]
N = len(arr)
# Function call
solve(arr, N)
# This code is contributed by sanjoy_62
C#
// C# program for the above approach
using System;
class GFG{
// Recursion Function to calculate the
// possible splitting
static int splitArray(int start, int end,
int[] arr,
int[] prefix_sum)
{
// If there are less than
// two elements, we cannot
// partition the sub-array.
if (start >= end)
return 0;
// Iterate from the start
// to end-1.
for(int k = start; k < end; ++k)
{
if ((prefix_sum[k] -
prefix_sum[start - 1]) ==
(prefix_sum[end] -
prefix_sum[k]))
{
// Recursive call to the left
// and the right sub-array.
return 1 + splitArray(start, k, arr,
prefix_sum) +
splitArray(k + 1, end, arr,
prefix_sum);
}
}
// If there is no such partition,
// then return 0
return 0;
}
// Function to find the total splitting
static void solve(int []arr, int n)
{
// Prefix array to store
// the prefix-sum using
// 1 based indexing
int []prefix_sum = new int[n + 1];
prefix_sum[0] = 0;
// Store the prefix-sum
for(int i = 1; i <= n; ++i)
{
prefix_sum[i] = prefix_sum[i - 1] +
arr[i - 1];
}
// Function Call to count the
// number of splitting
Console.Write(splitArray(1, n, arr,
prefix_sum));
}
// Driver Code
public static void Main(String[] args)
{
// Given array
int []arr = { 12, 3, 3, 0, 3, 3 };
int N = arr.Length;
// Function call
solve(arr, N);
}
}
// This code is contributed by Amit Katiyar
4
时间复杂度: O(N 2 )
辅助空间: O(N)