给定一个数组 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 现场工作专业课程和学生竞争性编程现场课程。