📜  O(sum)空间中的子集和问题

📅  最后修改于: 2021-04-27 05:37:08             🧑  作者: Mango

给定非负整数数组和值和,请确定给定集合的子集是否等于和。

例子:

Input : arr[] = {4, 1, 10, 12, 5, 2}, 
          sum = 9
Output : TRUE 
{4, 5} is a subset with sum 9.

Input : arr[] = {1, 8, 2, 5}, 
          sum = 4
Output : FALSE 
There exists no subset with sum 4.

我们在下面的文章中讨论了基于动态编程的解决方案。
动态编程|设置25(子总和问题)

上面讨论的解决方案需要O(n * sum)空间和O(n * sum)时间。我们可以优化空间。我们创建一个布尔2D数组子集[2] [sum + 1]。使用自底向上的方式,我们可以填写此表。在“ subset [2] [sum + 1]”中使用2的想法是,要填充一行,只需要前一行的值即可。因此,使用备用行或者将第一个作为当前,将第二个作为先前,或者将第一个作为先前,将第二个作为当前。

C++
// Returns true if there exists a subset
// with given sum in arr[]
#include 
#include 
  
bool isSubsetSum(int arr[], int n, int sum)
{
    // The value of subset[i%2][j] will be true 
    // if there exists a subset of sum j in 
    // arr[0, 1, ...., i-1]
    bool subset[2][sum + 1];
  
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= sum; j++) {
  
            // A subset with sum 0 is always possible 
            if (j == 0)
                subset[i % 2][j] = true; 
  
            // If there exists no element no sum 
            // is possible 
            else if (i == 0)
                subset[i % 2][j] = false; 
            else if (arr[i - 1] <= j)
                subset[i % 2][j] = subset[(i + 1) % 2]
             [j - arr[i - 1]] || subset[(i + 1) % 2][j];
            else
                subset[i % 2][j] = subset[(i + 1) % 2][j];
        }
    }
  
    return subset[n % 2][sum];
}
  
// Driver code
int main()
{
    int arr[] = { 6, 2, 5 };
    int sum = 7;
    int n = sizeof(arr) / sizeof(arr[0]);
    if (isSubsetSum(arr, n, sum) == true)
        printf("There exists a subset with given sum");
    else
        printf("No subset exists with given sum");
    return 0;
}


Java
// Java Program to get a subset with a 
// with a sum provided by the user
public class Subset_sum {
      
    // Returns true if there exists a subset
    // with given sum in arr[]
    static boolean isSubsetSum(int arr[], int n, int sum)
    {
        // The value of subset[i%2][j] will be true 
        // if there exists a subset of sum j in 
        // arr[0, 1, ...., i-1]
        boolean subset[][] = new boolean[2][sum + 1];
       
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= sum; j++) {
       
                // A subset with sum 0 is always possible 
                if (j == 0)
                    subset[i % 2][j] = true; 
       
                // If there exists no element no sum 
                // is possible 
                else if (i == 0)
                    subset[i % 2][j] = false; 
                else if (arr[i - 1] <= j)
                    subset[i % 2][j] = subset[(i + 1) % 2]
                 [j - arr[i - 1]] || subset[(i + 1) % 2][j];
                else
                    subset[i % 2][j] = subset[(i + 1) % 2][j];
            }
        }
       
        return subset[n % 2][sum];
    }
       
    // Driver code
    public static void main(String args[])
    {
        int arr[] = { 1, 2, 5 };
        int sum = 7;
        int n = arr.length;
        if (isSubsetSum(arr, n, sum) == true)
            System.out.println("There exists a subset with" + 
                                              "given sum");
        else
            System.out.println("No subset exists with" + 
                                           "given sum");
    }
}
// This code is contributed by Sumit Ghosh


Python
# Returns true if there exists a subset
# with given sum in arr[]
  
def isSubsetSum(arr, n, sum):
     
    # The value of subset[i%2][j] will be true 
    # if there exists a subset of sum j in 
    # arr[0, 1, ...., i-1]
    subset = [ [False for j in range(sum + 1)] for i in range(3) ]
   
    for i in range(n + 1):
        for j in range(sum + 1):
            # A subset with sum 0 is always possible 
            if (j == 0):
                subset[i % 2][j] = True
   
            # If there exists no element no sum 
            # is possible 
            elif (i == 0):
                subset[i % 2][j] = False
            elif (arr[i - 1] <= j):
                subset[i % 2][j] = subset[(i + 1) % 2][j - arr[i - 1]] or subset[(i + 1) 
                                                                               % 2][j]
            else:
                subset[i % 2][j] = subset[(i + 1) % 2][j]
                  
    return subset[n % 2][sum]
   
# Driver code
arr = [ 6, 2, 5 ]
sum = 7
n = len(arr)
if (isSubsetSum(arr, n, sum) == True):
    print ("There exists a subset with given sum")
else:
    print ("No subset exists with given sum")
      
# This code is contributed by Sachin Bisht


C#
// C# Program to get a subset with a 
// with a sum provided by the user 
  
using System;
  
public class Subset_sum { 
      
    // Returns true if there exists a subset 
    // with given sum in arr[] 
    static bool isSubsetSum(int []arr, int n, int sum) 
    { 
        // The value of subset[i%2][j] will be true 
        // if there exists a subset of sum j in 
        // arr[0, 1, ...., i-1] 
        bool [,]subset = new bool[2,sum + 1]; 
      
        for (int i = 0; i <= n; i++) { 
            for (int j = 0; j <= sum; j++) { 
      
                // A subset with sum 0 is always possible 
                if (j == 0) 
                    subset[i % 2,j] = true; 
      
                // If there exists no element no sum 
                // is possible 
                else if (i == 0) 
                    subset[i % 2,j] = false; 
                else if (arr[i - 1] <= j) 
                    subset[i % 2,j] = subset[(i + 1) % 2,j - arr[i - 1]] || subset[(i + 1) % 2,j]; 
                else
                    subset[i % 2,j] = subset[(i + 1) % 2,j]; 
            } 
        } 
      
        return subset[n % 2,sum]; 
    } 
      
    // Driver code 
    public static void Main() 
    { 
        int []arr = { 1, 2, 5 }; 
        int sum = 7; 
        int n = arr.Length; 
        if (isSubsetSum(arr, n, sum) == true) 
            Console.WriteLine("There exists a subset with" +
                                         "given sum"); 
        else
            Console.WriteLine("No subset exists with" + 
                                        "given sum"); 
    } 
} 
// This code is contributed by Ryuga


PHP


输出:

There exists a subset with given sum