给定非负整数数组和值和,请确定给定集合的子集是否等于和。
例子:
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