📜  打印相等和的数组集(分区问题)|设置 1

📅  最后修改于: 2021-09-17 07:06:37             🧑  作者: Mango

给定一个数组 arr[]。确定是否可以将数组拆分为两个集合,使得两个集合中元素的总和相等。如果可能,则打印两套。如果不可能,则输出-1。

例子 :

Input : arr = {5, 5, 1, 11}
Output : Set 1 = {5, 5, 1}, 
         Set 2 = {11}
Sum of both the sets is 11 and equal.

Input : arr = {1, 5, 3}
Output : -1
No partitioning results in equal sum sets.

我们已经在分区问题中讨论了一个解决方案,以确定数组是否可以分区。在这篇文章中,我们打印了两套也打印出来的。我们发布了两个向量 set1 和 set2 以及两个和变量 sum1 和 sum2。递归遍历数组。在每个数组位置有两种选择:将当前元素添加到 set 1 或 set 2。递归调用这两个条件并相应地更新向量 set1 和 set2。如果将当前元素添加到集合 1,则将当前元素添加到 sum1 并将其插入向量集合 1。如果当前元素包含在集合 2 中,则重复相同的操作。在数组遍历结束时比较两个总和。如果两个总和相等,则打印两个向量,否则回溯以检查其他可能性。

执行:

C++
// CPP program to print equal sum two subsets of
// an array if it can be partitioned into subsets.
#include 
using namespace std;
 
/// Function to print the equal sum sets of the array.
void printSets(vector set1, vector set2)
{
    int i;
 
    /// Print set 1.
    for (i = 0; i < set1.size(); i++) {
        cout << set1[i] << " ";
    }
 
    cout << "\n";
 
    /// Print set 2.
    for (i = 0; i < set2.size(); i++) {
        cout << set2[i] << " ";
    }
}
 
/// Utility function to find the sets of the array which
/// have equal sum.
bool findSets(int arr[], int n, vector& set1,
              vector& set2, int sum1, int sum2,
              int pos)
{
 
    /// If entire array is traversed, compare both the sums.
    if (pos == n) {
 
        /// If sums are equal print both sets and return
        /// true to show sets are found.
        if (sum1 == sum2) {
            printSets(set1, set2);
            return true;
        }
 
        /// If sums are not equal then return sets are not
        /// found.
        else
            return false;
    }
 
    /// Add current element to set 1.
    set1.push_back(arr[pos]);
 
    /// Recursive call after adding current element to
    /// set 1.
    bool res = findSets(arr, n, set1, set2, sum1 + arr[pos],
                        sum2, pos + 1);
 
    /// If this inclusion results in equal sum sets
    /// partition then return true to show desired sets are
    /// found.
    if (res)
        return res;
 
    /// If not then backtrack by removing current element
    /// from set1 and include it in set 2.
    set1.pop_back();
    set2.push_back(arr[pos]);
 
    /// Recursive call after including current element to
    /// set 2.
    res = findSets(arr, n, set1, set2, sum1,
                   sum2 + arr[pos], pos + 1);
    if (res == false)
        if (!set2.empty())
            set2.pop_back();
 
    return res;
}
 
/// Return true if array arr can be partitioned
/// into two equal sum sets or not.
bool isPartitionPoss(int arr[], int n)
{
    /// Calculate sum of elements in array.
    int sum = 0;
 
    for (int i = 0; i < n; i++)
        sum += arr[i];
 
    /// If sum is odd then array cannot be
    /// partitioned.
    if (sum % 2 != 0)
        return false;
 
    /// Declare vectors to store both the sets.
    vector set1, set2;
 
    /// Find both the sets.
    return findSets(arr, n, set1, set2, 0, 0, 0);
}
 
// Driver code
int main()
{
    int arr[] = { 5, 5, 1, 11 };
    int n = sizeof(arr) / sizeof(arr[0]);
    if (!isPartitionPoss(arr, n)) {
        cout << "-1";
    }
    return 0;
}


Java
// Java program to print equal sum two subsets
// of an array if it can be partitioned into
// subsets.
import java.io.*;
import java.util.*;
 
public class GFG {
 
    // Declare Lists to store both
    // the sets.
    static List set1 = new ArrayList();
    static List set2 = new ArrayList();
    /// Function to print the equal sum sets
    // of the array.
    static void printSets()
    {
        int i;
 
        /// Print set 1.
        for (i = 0; i < set1.size(); i++) {
            System.out.print(set1.get(i) + " ");
        }
 
        System.out.println();
 
        /// Print set 2.
        for (i = 0; i < set2.size(); i++) {
            System.out.print(set2.get(i) + " ");
        }
    }
 
    // Utility function to find the sets
    // of the array which have equal sum.
    static boolean findSets(Integer[] arr, int n,
                            int sum1, int sum2,
                            int pos)
    {
 
        // If entire array is traversed,
        // compare both the sums.
        if (pos == n) {
 
            // If sums are equal print
            // both sets and return true
            // to show sets are found.
            if (sum1 == sum2) {
                printSets();
                return true;
            }
 
            // If sums are not equal
            // then return sets are not
            // found.
            else
                return false;
        }
 
        // Add current element to set 1.
        set1.add(arr[pos]);
 
        // Recursive call after adding
        // current element to set 1.
        boolean res = findSets(arr, n, sum1 + arr[pos],
                               sum2, pos + 1);
 
        // If this inclusion results in
        // equal sum sets partition then
        // return true to show desired
        // sets are found.
        if (res == true)
            return res;
 
        // If not then backtrack by removing
        // current element from set1 and
        // include it in set 2.
        set1.remove(set1.size() - 1);
        set2.add(arr[pos]);
 
        // Recursive call after including
        // current element to set 2.
        res = findSets(arr, n, sum1, sum2
                                         + arr[pos],
                       pos + 1);
 
        if (res == false)
            if (set2.size() > 0)
                set2.remove(set2.size() - 1);
 
        return res;
    }
 
    // Return true if array arr can be
    // partitioned into two equal sum
    // sets or not.
    static boolean isPartitionPoss(Integer[] arr,
                                   int n)
    {
        // Calculate sum of elements in
        // array.
        int sum = 0;
 
        for (int i = 0; i < n; i++)
            sum += arr[i];
 
        // If sum is odd then array cannot
        // be partitioned.
        if (sum % 2 != 0)
            return false;
 
        /// Find both the sets.
        return findSets(arr, n, 0, 0, 0);
    }
 
    // Driver code
    public static void main(String args[])
    {
        Integer[] arr = { 5, 5, 1, 11 };
        int n = arr.length;
        if (isPartitionPoss(arr, n) == false) {
            System.out.print("-1");
        }
    }
}
 
// This code is contributed by Manish Shaw
// (manishshaw1)


Python3
# Python3 program to print equal sum two subsets of
# an array if it can be partitioned into subsets.
 
# Function to print the equal sum sets of the array.
def printSets(set1, set2) :
 
    # Print set 1.
    for i in range(0, len(set1)) :
        print ("{} ".format(set1[i]), end ="");
    print ("")
 
    # Print set 2.
    for i in range(0, len(set2)) :
        print ("{} ".format(set2[i]), end ="");
    print ("")
 
# Utility function to find the sets of the
# array which have equal sum.
def findSets(arr, n, set1, set2, sum1, sum2, pos) :
 
 
    # If entire array is traversed, compare both
    # the sums.
    if (pos == n) :
         
        # If sums are equal print both sets and
        # return true to show sets are found.
        if (sum1 == sum2) :
            printSets(set1, set2)
            return True
 
        # If sums are not equal then return
        # sets are not found.
        else :
            return False    
 
    # Add current element to set 1.
    set1.append(arr[pos])
 
    # Recursive call after adding current
    # element to set 1.
    res = findSets(arr, n, set1, set2,
               sum1 + arr[pos], sum2, pos + 1)
 
    # If this inclusion results in an equal sum
    # sets partition then return true to show
    # desired sets are found.
    if (res) :
        return res
 
    # If not then backtrack by removing current
    # element from set1 and include it in set 2.
    set1.pop()
    set2.append(arr[pos])
 
    # Recursive call after including current
    # element to set 2 and removing the element
    # from set 2 if it returns False
    res= findSets(arr, n, set1, set2, sum1,
                     sum2 + arr[pos], pos + 1)
    if not res:       
        set2.pop()
    return res
 
# Return true if array arr can be partitioned
# into two equal sum sets or not.
def isPartitionPoss(arr, n) :
 
    # Calculate sum of elements in array.
    sum = 0
 
    for i in range(0, n):
        sum += arr[i]
 
    # If sum is odd then array cannot be
    # partitioned.
    if (sum % 2 != 0) :
        return False
 
    # Declare vectors to store both the sets.
    set1 = []
    set2 = []
 
    # Find both the sets.
    return findSets(arr, n, set1, set2, 0, 0, 0)
 
# Driver code
arr = [5, 5, 1, 11]
n = len(arr)
if (isPartitionPoss(arr, n) == False) :
    print ("-1")
     
# This code is contributed by Manish Shaw
# (manishshaw1)


C#
// C# program to print equal sum two subsets
// of an array if it can be partitioned into
// subsets.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
 
class GFG {
 
    /// Function to print the equal sum sets
    // of the array.
    static void printSets(List set1,
                          List set2)
    {
        int i;
 
        /// Print set 1.
        for (i = 0; i < set1.Count; i++) {
            Console.Write(set1[i] + " ");
        }
 
        Console.WriteLine();
 
        /// Print set 2.
        for (i = 0; i < set2.Count; i++) {
            Console.Write(set2[i] + " ");
        }
    }
 
    // Utility function to find the sets
    // of the array which have equal sum.
    static bool findSets(int[] arr, int n,
                         ref List set1,
                         ref List set2,
                         int sum1, int sum2,
                         int pos)
    {
 
        // If entire array is traversed,
        // compare both the sums.
        if (pos == n) {
 
            // If sums are equal print
            // both sets and return true
            // to show sets are found.
            if (sum1 == sum2) {
                printSets(set1, set2);
                return true;
            }
 
            // If sums are not equal
            // then return sets are not
            // found.
            else
                return false;
        }
 
        // Add current element to set 1.
        set1.Add(arr[pos]);
 
        // Recursive call after adding
        // current element to set 1.
        bool res = findSets(arr, n, ref set1,
                            ref set2, sum1 + arr[pos],
                            sum2, pos + 1);
 
        // If this inclusion results in
        // equal sum sets partition then
        // return true to show desired
        // sets are found.
        if (res == true)
            return res;
 
        // If not then backtrack by removing
        // current element from set1 and
        // include it in set 2.
        set1.RemoveAt(set1.Count - 1);
        set2.Add(arr[pos]);
 
        // Recursive call after including
        // current element to set 2.
        res = findSets(arr, n, ref set1,
                       ref set2, sum1, sum2
                                           + arr[pos],
                       pos + 1);
 
        if (res == false)
            if (set2.Count > 0)
                set2.RemoveAt(set2.Count - 1);
 
        return res;
    }
 
    // Return true if array arr can be
    // partitioned into two equal sum
    // sets or not.
    static bool isPartitionPoss(int[] arr,
                                int n)
    {
        // Calculate sum of elements in
        // array.
        int sum = 0;
 
        for (int i = 0; i < n; i++)
            sum += arr[i];
 
        // If sum is odd then array cannot
        // be partitioned.
        if (sum % 2 != 0)
            return false;
 
        // Declare Lists to store both
        // the sets.
        List set1 = new List();
        List set2 = new List();
 
        /// Find both the sets.
        return findSets(arr, n, ref set1,
                        ref set2, 0, 0, 0);
    }
 
    // Driver code
    public static void Main()
    {
        int[] arr = { 5, 5, 1, 11 };
        int n = arr.Length;
        if (isPartitionPoss(arr, n) == false) {
            Console.Write("-1");
        }
    }
}
 
// This code is contributed by Manish Shaw
// (manishshaw1)


PHP


Javascript


输出:

5 5 1
11

时间复杂度:指数 O(2^n)
辅助空间: O(n)(不考虑函数调用栈的大小)

打印数组的相等和集(分区问题)| 2套

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程