📌  相关文章
📜  将数组分为相同总和的两半

📅  最后修改于: 2021-04-23 18:37:41             🧑  作者: Mango

给定一个偶数大小的整数数组。我们需要找到是否有可能将数组元素分为两组,从而满足以下条件。

  1. 两个子集的大小相同。
  2. 机器人集中的元素总数是相同的。
  3. 每个元素都是两个集合之一的一部分。

例子 :

Input: arr[] = {1, 3, 2, 1, 2, 1}
Output : Yes
Explanation: We can get two subsets
as {1, 3, 1} and {2, 2, 1}

Input: {1, 2, 3, 4, 5, 6}
Output : No

这个想法是基于以下帖子的方法1。
在大小为n的给定数组中打印r元素的所有可能组合

我们生成大小为n / 2的所有子集。对于每个子集,我们检查其总和是否为2的总和。

C++
// Program to check if we can divide an array into two
// halves such that sum of the two is same.
#include 
using namespace std;
  
bool combinationUtil(int arr[], int half[], int start, int end,
                     int index, int n, int sum);
  
// Returns true if it is possible to divide array into two halves.
// of same sum. This function mainly uses combinationUtil()
bool isPossible(int arr[], int n)
{
    // If size of array is not even.
    if (n % 2 != 0)
        return false;
  
    // If sum of array is not even.
    int sum = accumulate(arr, arr + n, 0);
    if (sum % 2 != 0)
        return false;
  
    // A temporary array to store all combination one by one
    int half[n / 2];
  
    // Print all combination using temporary array 'half[]'
    return combinationUtil(arr, half, 0, n - 1, 0, n, sum);
}
  
/* arr[] ---> Input Array
   half[] ---> Temporary array to store current combination
               of size n/2
   start & end ---> Staring and Ending indexes in arr[]
   index ---> Current index in half[] */
bool combinationUtil(int arr[], int half[], int start, int end,
                     int index, int n, int sum)
{
    // Current combination is ready to be printed, print it
    if (index == n / 2) {
        int curr_sum = accumulate(half, half + n / 2, 0);
        return (curr_sum + curr_sum == sum);
    }
  
    // replace index with all possible elements. The condition
    // "end-i+1 >= n/2-index" makes sure that including one element
    // at index will make a combination with remaining elements
    // at remaining positions
    for (int i = start; i <= end && end - i + 1 >= n/2 - index; i++) {
        half[index] = arr[i];
        if (combinationUtil(arr, half, i + 1, end, index + 1, n, sum))
            return true;
    }
  
    return false;
}
  
// Driver program to test above functions
int main()
{
    int arr[] = { 1, 2, 4, 4, 5, 6 };
    int n = sizeof(arr) / sizeof(arr[0]);
    if (isPossible(arr, n))
        cout << "Yes";
    else
        cout << "No";
    return 0;
}


Java
// Java program to check if we can
// divide an array into two halves
// such that sum of the two is same.
public class DivideArray{ 
      
    static int accumulate(int arr[], int first,
                                     int last)
    {
        int init = 0;
        for (int i = first; i< last; i++) {
            init = init + arr[i];
        }
      
        return init;
    }
  
    // Returns true if it is possible to divide 
    // array into two halves of same sum. 
    // This function mainly uses combinationUtil()
    static Boolean isPossible(int arr[], int n)
    {
        // If size of array is not even.
        if (n % 2 != 0)
            return false;
  
        // If sum of array is not even.
        int sum = accumulate(arr, 0, n);
        if (sum % 2 != 0)
            return false;
  
        // A temporary array to store all 
        // combination one by one int k=n/2;
        int half[] = new int[n/2];
  
        // Print all combination using temporary
        // array 'half[]'
        return combinationUtil(arr, half, 0, n - 1,
                                0, n, sum);
    }
  
    /* arr[] ---> Input Array
    half[] ---> Temporary array to store current 
                combination of size n/2
    start & end ---> Staring and Ending indexes in arr[]
    index ---> Current index in half[] */
    static Boolean combinationUtil(int arr[], int half[], 
                                   int start, int end,
                                   int index, int n,
                                   int sum)
    {
        // Current combination is ready to 
        // be printed, print it
        if (index == n / 2) {
            int curr_sum = accumulate(half, 0 , n/2);
            return (curr_sum + curr_sum == sum);
        }
  
        // replace index with all possible elements. 
        // The condition "end-i+1 >= n/2-index" makes
        // sure that including one element at index 
        // will make a combination with remaining
        // elements at remaining positions
        for (int i = start; i <= end && end - i + 1 >= 
                                  n/2 - index; i++) {
            half[index] = arr[i];
            if (combinationUtil(arr, half, i + 1, end, 
                                 index + 1, n, sum))
                return true;
        }
  
        return false;
    }
  
    // Driver code
    public static void main(String[] s)
    {
        int arr[] = {1, 2, 4, 4, 5, 6 };
          
        if (isPossible(arr, arr.length))
        System.out.println("Yes");
        else
        System.out.println("NO");
    }
}
  
// This code is contributed by Prerna Saini


Python3
# Python3 program to check if 
# we can divide an array into two
# halves such that sum of the two is same.
  
# Returns true if it is possible to divide 
# array into two halves of same sum. 
# This function mainly uses combinationUtil()
def isPossible(arr, n):
  
    # If size of array is not even
    if n % 2 != 0:
        return False
  
    # If sum of array is not even.
    s = sum(arr)
    if s % 2 != 0:
        return False
  
    # A temporary array to store 
    # all combination one by one
    half = [0] * (n // 2)
  
    # Print all combination using 
    # temporary array 'half[]'
    return combinationUtil(arr, half, 0, 
                           n - 1, 0, n, s)
  
'''
arr[] ---> Input Array 
half[] ---> Temporary array to store current 
            combination of size n/2 
start & end ---> Staring and Ending indexes in arr[] 
index ---> Current index in half[]
'''
def combinationUtil(arr, half, start, end, index, n, s):
  
    # Current combination is 
    # ready to be printed, print it
    if index == n // 2:
        curr_sum = sum(half)
        if (curr_sum + curr_sum == s):
            return True 
        else: 
            return False
  
    # replace index with all possible elements. 
    # The condition "end-i+1 >= n/2-index" 
    # makes sure that including one element
    # at index will make a combination with 
    # remaining elements at remaining positions
    i = start
    while i <= end and (end - i + 1) >= (n // 2 - index):
        half[index] = arr[i]
        if combinationUtil(arr, half, i + 1, end, 
                           index + 1, n, s):
            return True
        i += 1
  
    return False
  
# Driver Code
if __name__ == "__main__":
    arr = [1, 2, 4, 4, 5, 6]
    n = len(arr)
  
    if isPossible(arr, n):
        print("Yes")
    else:
        print("No")
  
# This code is contributed by
# sanjeev2552


C#
// C# program to check if we can 
// divide an array into two halves 
// such that sum of the two is same.
using System;
   
public class DivideArray{ 
      
    static int accumulate(int []arr, int first, 
                                    int last) 
    { 
        int init = 0; 
        for (int i = first; i< last; i++) { 
            init = init + arr[i]; 
        } 
      
        return init; 
    } 
  
    // Returns true if it is possible to divide 
    // array into two halves of same sum. 
    // This function mainly uses combinationUtil() 
    static Boolean isPossible(int []arr, int n) 
    { 
        // If size of array is not even. 
        if (n % 2 != 0) 
            return false; 
  
        // If sum of array is not even. 
        int sum = accumulate(arr, 0, n); 
        if (sum % 2 != 0) 
            return false; 
  
        // A temporary array to store all 
        // combination one by one int k=n/2; 
        int []half = new int[n/2]; 
  
        // Print all combination using temporary 
        // array 'half[]' 
        return combinationUtil(arr, half, 0, n - 1, 
                                0, n, sum); 
    } 
  
    /* arr[] ---> Input Array 
    half[] ---> Temporary array to store current 
                combination of size n/2 
    start & end ---> Staring and Ending indexes in arr[] 
    index ---> Current index in half[] */
    static Boolean combinationUtil(int []arr, int []half, 
                                int start, int end, 
                                int index, int n, 
                                int sum) 
    { 
        // Current combination is ready to 
        // be printed, print it 
        if (index == n / 2) { 
            int curr_sum = accumulate(half, 0 , n/2); 
            return (curr_sum + curr_sum == sum); 
        } 
  
        // replace index with all possible elements. 
        // The condition "end-i+1 >= n/2-index" makes 
        // sure that including one element at index 
        // will make a combination with remaining 
        // elements at remaining positions 
        for (int i = start; i <= end && end - i + 1 >= 
                                n/2 - index; i++) { 
            half[index] = arr[i]; 
            if (combinationUtil(arr, half, i + 1, end, 
                                index + 1, n, sum)) 
                return true; 
        } 
  
        return false; 
    } 
  
    // Driver code 
    public static void Main() 
    { 
        int []arr = {1, 2, 4, 4, 5, 6 }; 
          
        if (isPossible(arr, arr.Length)) 
        Console.WriteLine("Yes"); 
        else
        Console.WriteLine("NO"); 
    } 
} 
  
// This code is contributed by PrinciRaj1992


输出:

Yes