给定数组arr []和其中的索引。查找是否可以将数组arr []划分为两个不相交的集合,以使两个集合的总和相等,并且没有一个集合包含arr [index]
例子 :
Input : arr[] = {2, 1, 3, 4},
index = 2
Output : No
We need to exclude arr[2] which is 3.
Possible sets are :
Set 1: (2, 1), Set 2: 4, sum = 3≠4
Set 1: 2, Set 2: (4, 1), sum = 2≠5
Set 1: 1, Set 2: (4, 2), sum = 1≠6
Neither of the sums are equal.
Input : arr[] = {2, 5, 1, 4, 0},
index = 4
Output : Yes
Set 1 : (2, 4), sum = 6
Set 2 : (5, 1), sum = 6
方法:此问题是分区问题的一种变体,具有一个额外的约束,即索引既不能包含在两个分区的数组集中,也不能包含索引。
首先找到不包括第index个元素的数组的和S。如果总和是偶数,则可以对数组进行分区,否则不能进行分区。如果总和是偶数,则定义两个变量set1Sum和set2Sum来存储两个集合的总和。
可以递归确定set1Sum是否等于set2Sum。从位置0开始,递归遍历数组。在每个数组位置,有两个选择:在集合1或集合2中包括当前数组元素。通过首先在集合1中包括当前元素,然后在集合2中包括当前元素,来递归调用这两个条件。被排除,然后递归调用下一个职位而不更新任何金额。当遍历整个数组时,请检查两个集合的和是否相等。如果总和相等,则找到结果,否则回溯并检查其他可能性。
执行:
C++
// C++ program to determine whether an array can be
// partitioned into two equal sum sets when an index
// is always excluded from both sets.
#include
using namespace std;
// Utility function to partition array into two sets
// and check whether sum of both sets are equal or not.
bool isSubsetSumPoss(int arr[], int n, int set1Sum,
int set2Sum, int index, int pos)
{
// If the entire array is traversed, then check
// whether sum of both the sets are equal or not.
if (pos == n)
return (set1Sum == set2Sum);
// If current position is the index to be excluded
// then call the function for next position without
// updating any sum.
if (pos == index)
isSubsetSumPoss(arr, n, set1Sum,
set2Sum, index, pos + 1);
// Each element can be included either in
// set 1 or in set 2. Call function for
// both the cases.
return isSubsetSumPoss(arr, n, set1Sum + arr[pos],
set2Sum, index, pos + 1)
|| isSubsetSumPoss(arr, n, set1Sum, set2Sum +
arr[pos], index, pos + 1);
}
// Function that calls the main utility
// function and returns whether array can
// be partitioned into two sets or not.
bool canPartition(int arr[], int n, int index)
{
// Calculate sum of entire array
// excluding position index.
int sum = 0;
for (int i = 0; i < n; i++) {
if (i == index)
continue;
sum += arr[i];
}
// If sum is not even then array
// cannot be partitioned into two
// equal sum sets.
if (sum % 2 != 0)
return false;
// If sum is even call utility function.
return isSubsetSumPoss(arr, n, 0, 0,
index, 0);
}
int main()
{
int arr[] = { 2, 5, 1, 4, 0 };
int index = 4;
int n = sizeof(arr) / sizeof(arr[0]);
if (canPartition(arr, n, index))
cout << "Yes";
else
cout << "No";
return 0;
}
Java
// Java program to determine whether an array
// can be partitioned into two equal sum
// sets when an index is always excluded
// from both sets.
import java.io.*;
import java.util.*;
public class GFG {
// Utility function to partition array
// into two sets and check whether sum
// of both sets are equal or not.
static boolean isSubsetSumPoss(int []arr,
int n, int set1Sum, int set2Sum,
int index, int pos)
{
// If the entire array is traversed,
// then check whether sum of both
// the sets are equal or not.
if (pos == n)
return (set1Sum == set2Sum);
// If current position is the index
// to be excluded then call the
// function for next position without
// updating any sum.
if (pos == index)
isSubsetSumPoss(arr, n, set1Sum,
set2Sum, index, pos + 1);
// Each element can be included
// either in set 1 or in set 2.
// Call function for both the cases.
return isSubsetSumPoss(arr, n, set1Sum
+ arr[pos], set2Sum, index, pos + 1)
|| isSubsetSumPoss(arr, n, set1Sum,
set2Sum + arr[pos], index, pos + 1);
}
// Function that calls the main utility
// function and returns whether array can
// be partitioned into two sets or not.
static boolean canPartition(int []arr, int n,
int index)
{
// Calculate sum of entire array
// excluding position index.
int sum = 0;
for (int i = 0; i < n; i++) {
if (i == index)
continue;
sum += arr[i];
}
// If sum is not even then array
// cannot be partitioned into two
// equal sum sets.
if (sum % 2 != 0)
return false;
// If sum is even call utility function.
return isSubsetSumPoss(arr, n, 0, 0,
index, 0);
}
// Driver code
public static void main(String args[])
{
int []arr = { 2, 5, 1, 4, 0 };
int index = 4;
int n = arr.length;
if (canPartition(arr, n, index))
System.out.print("Yes");
else
System.out.print("No");
}
}
// This code is contributed by Manish Shaw
// (manishshaw1)
Python3
# Python3 program to determine whether an array can be
# partitioned into two equal sum sets when an index
# is always excluded from both sets.
# Utility function to partition array into two sets
# and check whether sum of both sets are equal or not.
def isSubsetSumPoss(arr, n, set1Sum, set2Sum, index, pos) :
# If the entire array is traversed, then check
# whether sum of both the sets are equal or not.
if (pos == n) :
return (set1Sum == set2Sum)
# If current position is the index to be excluded
# then call the function for next position without
# updating any sum.
if (pos == index) :
isSubsetSumPoss(arr, n, set1Sum, set2Sum,
index, pos + 1)
# Each element can be included either in
# set 1 or in set 2. Call function for
# both the cases.
return (isSubsetSumPoss(arr, n, set1Sum + arr[pos],
set2Sum, index, pos + 1)
or isSubsetSumPoss(arr, n, set1Sum,
set2Sum + arr[pos], index, pos + 1))
# Function that calls the main utility
# function and returns whether array can
# be partitioned into two sets or not.
def canPartition(arr, n, index) :
# Calculate sum of entire array
# excluding position index.
sum = 0
for i in range (0, n) :
if (i == index) :
continue
sum += arr[i]
# If sum is not even then array
# cannot be partitioned into two
# equal sum sets.
if (sum % 2 != 0) :
return false
# If sum is even call utility function.
return isSubsetSumPoss(arr, n, 0, 0, index, 0)
# Driver Code
arr = [ 2, 5, 1, 4, 0 ]
index = 4
n = len(arr)
if (canPartition(arr, n, index)) :
print ("Yes")
else :
print ("No")
# This code is contributed by Manish Shaw
# (manishshaw1)
C#
// C# program to determine whether an array
// can be partitioned into two equal sum
// sets when an index is always excluded
// from both sets.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
class GFG {
// Utility function to partition array
// into two sets and check whether sum
// of both sets are equal or not.
static bool isSubsetSumPoss(int []arr,
int n, int set1Sum, int set2Sum,
int index, int pos)
{
// If the entire array is traversed,
// then check whether sum of both
// the sets are equal or not.
if (pos == n)
return (set1Sum == set2Sum);
// If current position is the index
// to be excluded then call the
// function for next position without
// updating any sum.
if (pos == index)
isSubsetSumPoss(arr, n, set1Sum,
set2Sum, index, pos + 1);
// Each element can be included
// either in set 1 or in set 2.
// Call function for both the cases.
return isSubsetSumPoss(arr, n, set1Sum
+ arr[pos], set2Sum, index, pos + 1)
|| isSubsetSumPoss(arr, n, set1Sum,
set2Sum + arr[pos], index, pos + 1);
}
// Function that calls the main utility
// function and returns whether array can
// be partitioned into two sets or not.
static bool canPartition(int []arr, int n,
int index)
{
// Calculate sum of entire array
// excluding position index.
int sum = 0;
for (int i = 0; i < n; i++) {
if (i == index)
continue;
sum += arr[i];
}
// If sum is not even then array
// cannot be partitioned into two
// equal sum sets.
if (sum % 2 != 0)
return false;
// If sum is even call utility function.
return isSubsetSumPoss(arr, n, 0, 0,
index, 0);
}
// Driver code
public static void Main()
{
int []arr = { 2, 5, 1, 4, 0 };
int index = 4;
int n = arr.Length;
if (canPartition(arr, n, index))
Console.Write("Yes");
else
Console.Write("No");
}
}
// This code is contributed by Manish Shaw
// (manishshaw1)
PHP
Javascript
输出 :
Yes
时间复杂度:指数O(2 ^ n)
练习:尝试迭代解决此问题。