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

📅  最后修改于: 2021-05-14 00:53:49             🧑  作者: 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


输出:
4

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