📌  相关文章
📜  一个数组可以重复划分为两个等和的子数组的次数

📅  最后修改于: 2021-10-26 06:08:37             🧑  作者: Mango

给定一个大小为N的数组arr[] ,任务是找到该数组可以重复划分为两个子数组的次数,使得两个子数组的元素之和相同。
例子:

方法:想法是使用递归。以下是步骤:

  1. 找到给定数组 arr[] 的前缀和并将其存储在数组pref[] 中
  2. 从开始位置迭代到结束位置。
  3. 对于每个可能的分区索引(比如K ),如果prefix_sum[K] – prefix_sum[start-1] = prefix_sum[end] – prefix_sum[k]那么分区是有效的。
  4. 如果在上述步骤中分区有效,则分别对左右子阵列进行处理,并确定这两个子阵列是否构成有效的分区。
  5. 对左右分区重复第 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


Javascript


输出:
4

时间复杂度: O(N 2 )
辅助空间: O(N)