📜  等和数组分区,不包括给定元素

📅  最后修改于: 2021-05-07 18:35:46             🧑  作者: Mango

给定数组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)
练习:尝试迭代解决此问题。