总和小于 Array 总和的子集计数
给定一个大小为N的数组arr[ ] 。任务是在数组中出现 0 时找到总和为 ( 数组的总和- 1 ) 的子集数,如果没有子集可能,则返回 -1。
例子:
Input: arr[ ] : {3, 0, 5, 2, 4}
Output: -1
Explanation: sum of array arr[ ] is 14 and there is not any subset with sum 13.
Input: arr[ ] : {0, 0, 2, 1}
Output: 4
Explanation: sum of array arr[ ] is 3 and {0, 2}, {0, 2}, {0, 0, 2}, {2} are the four subsets with sum 2 .
朴素方法:该任务可以通过使用递归生成数组的所有可能子集来解决,如果遇到总和为(数组之和 - 1)的子集,则增加计数。
下面是上述方法的实现:
C++
// C++ program to print the count of
// subsets with sum equal to the given value X
#include
using namespace std;
// Recursive function to return the count
// of subsets with sum equal to the given value
int subsetSum(int arr[], int n, int i,
int sum, int count)
{
// The recursion is stopped at N-th level
// where all the subsets of the given array
// have been checked
if (i == n) {
// Incrementing the count if sum is
// equal to 0 and returning the count
if (sum == 0) {
count++;
}
return count;
}
// Recursively calling the
// function for two cases
// Either the element can be
// counted in the subset
// If the element is counted,
// then the remaining sum
// to be checked is
// sum - the selected element
// If the element is not included,
// then the remaining sum
// to be checked is the total sum
count = subsetSum(arr, n, i + 1,
sum - arr[i], count);
count = subsetSum(arr, n, i + 1,
sum, count);
return count == 0 ? -1 : count;
}
// Driver code
int main()
{
int arr[] = { 0, 0, 2, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
// Sum of array - 1
int sum = accumulate(arr, arr + n, 0) - 1;
cout << subsetSum(arr, n, 0, sum, 0);
}
Java
// Java program to print the count of
// subsets with sum equal to the given value X
public class GFG {
// Recursive function to return the count
// of subsets with sum equal to the given value
static int subsetSum(int arr[], int n, int i,
int sum, int count)
{
// The recursion is stopped at N-th level
// where all the subsets of the given array
// have been checked
if (i == n) {
// Incrementing the count if sum is
// equal to 0 and returning the count
if (sum == 0) {
count++;
}
return count;
}
// Recursively calling the
// function for two cases
// Either the element can be
// counted in the subset
// If the element is counted,
// then the remaining sum
// to be checked is
// sum - the selected element
// If the element is not included,
// then the remaining sum
// to be checked is the total sum
count = subsetSum(arr, n, i + 1,
sum - arr[i], count);
count = subsetSum(arr, n, i + 1,
sum, count);
return count == 0 ? -1 : count;
}
static int accumulate(int []arr)
{
int sum = 0;
for(int i = 0; i < arr.length; i++)
sum += arr[i];
return sum;
}
// Driver code
public static void main (String[] args)
{
int arr[] = { 0, 0, 2, 1 };
int n = arr.length;
// Sum of array - 1
int sum = accumulate(arr) - 1;
System.out.println(subsetSum(arr, n, 0, sum, 0));
}
}
// This code is contributed by AnkThon
Python3
# Python program to print the count of
# subsets with sum equal to the given value X
# Recursive function to return the count
# of subsets with sum equal to the given value
def subsetSum(arr, n, i, sum, count):
# The recursion is stopped at N-th level
# where all the subsets of the given array
# have been checked
if (i == n):
# Incrementing the count if sum is
# equal to 0 and returning the count
if (sum == 0):
count += 1
return count
# Recursively calling the
# function for two cases
# Either the element can be
# counted in the subset
# If the element is counted,
# then the remaining sum
# to be checked is
# sum - the selected element
# If the element is not included,
# then the remaining sum
# to be checked is the total sum
count = subsetSum(arr, n, i + 1,
sum - arr[i], count)
count = subsetSum(arr, n, i + 1,
sum, count)
return - 1 if count == 0 else count
def accumulate(arr):
sum = 0
for i in range(len(arr)):
sum += arr[i]
return sum
# Driver code
arr = [0, 0, 2, 1]
n = len(arr)
# Sum of array - 1
sum = accumulate(arr) - 1
print(subsetSum(arr, n, 0, sum, 0))
# This code is contributed by gfgking
C#
// C# program to print the count of
// subsets with sum equal to the given value X
using System;
public class GFG {
// Recursive function to return the count
// of subsets with sum equal to the given value
static int subsetSum(int []arr, int n, int i,
int sum, int count)
{
// The recursion is stopped at N-th level
// where all the subsets of the given array
// have been checked
if (i == n) {
// Incrementing the count if sum is
// equal to 0 and returning the count
if (sum == 0) {
count++;
}
return count;
}
// Recursively calling the
// function for two cases
// Either the element can be
// counted in the subset
// If the element is counted,
// then the remaining sum
// to be checked is
// sum - the selected element
// If the element is not included,
// then the remaining sum
// to be checked is the total sum
count = subsetSum(arr, n, i + 1,
sum - arr[i], count);
count = subsetSum(arr, n, i + 1,
sum, count);
return count == 0 ? -1 : count;
}
static int accumulate(int []arr)
{
int sum = 0;
for(int i = 0; i < arr.Length; i++)
sum += arr[i];
return sum;
}
// Driver code
public static void Main (string[] args)
{
int []arr = { 0, 0, 2, 1 };
int n = arr.Length;
// Sum of array - 1
int sum = accumulate(arr) - 1;
Console.WriteLine(subsetSum(arr, n, 0, sum, 0));
}
}
// This code is contributed by AnkThon
Javascript
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to find the no of
// possible subsets
int subsetCount(int arr[], int n)
{
// Count the no of 0s and 1s
// in array
int zeros = 0, ones = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == 0) {
zeros++;
}
else if (arr[i] == 1) {
ones++;
}
}
// Store no of ways to remove 0
int no_of_ways_0 = pow(2, zeros);
// Store no of ways to remove 1
int no_of_ways_1 = ones;
// Store the total count of subsets
int count_subset = no_of_ways_0
* no_of_ways_1;
// If there is no subset possible
// with required sum, return -1
if (count_subset == 0)
return -1;
return count_subset;
}
// Driver Code
int main()
{
int arr[] = { 0, 0, 2, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << subsetCount(arr, n);
}
Java
// Java implementation of the above approach
import java.util.*;
public class GFG
{
// Function to find the no of
// possible subsets
static int subsetCount(int []arr, int n)
{
// Count the no of 0s and 1s
// in array
int zeros = 0, ones = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == 0) {
zeros++;
}
else if (arr[i] == 1) {
ones++;
}
}
// Store no of ways to remove 0
int no_of_ways_0 = (int)Math.pow(2, zeros);
// Store no of ways to remove 1
int no_of_ways_1 = ones;
// Store the total count of subsets
int count_subset = no_of_ways_0
* no_of_ways_1;
// If there is no subset possible
// with required sum, return -1
if (count_subset == 0)
return -1;
return count_subset;
}
// Driver Code
public static void main(String args[])
{
int []arr = { 0, 0, 2, 1 };
int n = arr.length;
System.out.println(subsetCount(arr, n));
}
}
// This code is contributed by Samim Hossain Mondal.
Python3
# Python 3 implementation of the above approach
# Function to find the no of
# possible subsets
def subsetCount(arr, n):
# Count the no of 0s and 1s
# in array
zeros = 0
ones = 0
for i in range(n):
if (arr[i] == 0):
zeros += 1
elif (arr[i] == 1):
ones += 1
# Store no of ways to remove 0
no_of_ways_0 = pow(2, zeros)
# Store no of ways to remove 1
no_of_ways_1 = ones
# Store the total count of subsets
count_subset = no_of_ways_0 * no_of_ways_1
# If there is no subset possible
# with required sum, return -1
if (count_subset == 0):
return -1
return count_subset
# Driver Code
if __name__ == "__main__":
arr = [0, 0, 2, 1]
n = len(arr)
print(subsetCount(arr, n))
# This code is contributed by ukasp.
C#
// C# implementation of the above approach
using System;
class GFG
{
// Function to find the no of
// possible subsets
static int subsetCount(int []arr, int n)
{
// Count the no of 0s and 1s
// in array
int zeros = 0, ones = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == 0) {
zeros++;
}
else if (arr[i] == 1) {
ones++;
}
}
// Store no of ways to remove 0
int no_of_ways_0 = (int)Math.Pow(2, zeros);
// Store no of ways to remove 1
int no_of_ways_1 = ones;
// Store the total count of subsets
int count_subset = no_of_ways_0
* no_of_ways_1;
// If there is no subset possible
// with required sum, return -1
if (count_subset == 0)
return -1;
return count_subset;
}
// Driver Code
public static void Main()
{
int []arr = { 0, 0, 2, 1 };
int n = arr.Length;
Console.Write(subsetCount(arr, n));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出:
4
时间复杂度: O(2 n ),其中 n = 数组长度
辅助空间:O(n),递归栈空间
有效的方法:上述方法可以通过找到一个可能的子集来优化,其总和为(array_sum – 1) 从数组中删除0和一个1 ,使子集和等于(数组的总和 – 1 ) 。
- 如果数组中有k个零,那么有2^k (k 是零的数量)方法可以从数组中删除0 。
- 这两者相乘(没有删除0的方法和没有删除1的方法)导致没有可能的子集。
下面是上述代码的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to find the no of
// possible subsets
int subsetCount(int arr[], int n)
{
// Count the no of 0s and 1s
// in array
int zeros = 0, ones = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == 0) {
zeros++;
}
else if (arr[i] == 1) {
ones++;
}
}
// Store no of ways to remove 0
int no_of_ways_0 = pow(2, zeros);
// Store no of ways to remove 1
int no_of_ways_1 = ones;
// Store the total count of subsets
int count_subset = no_of_ways_0
* no_of_ways_1;
// If there is no subset possible
// with required sum, return -1
if (count_subset == 0)
return -1;
return count_subset;
}
// Driver Code
int main()
{
int arr[] = { 0, 0, 2, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << subsetCount(arr, n);
}
Java
// Java implementation of the above approach
import java.util.*;
public class GFG
{
// Function to find the no of
// possible subsets
static int subsetCount(int []arr, int n)
{
// Count the no of 0s and 1s
// in array
int zeros = 0, ones = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == 0) {
zeros++;
}
else if (arr[i] == 1) {
ones++;
}
}
// Store no of ways to remove 0
int no_of_ways_0 = (int)Math.pow(2, zeros);
// Store no of ways to remove 1
int no_of_ways_1 = ones;
// Store the total count of subsets
int count_subset = no_of_ways_0
* no_of_ways_1;
// If there is no subset possible
// with required sum, return -1
if (count_subset == 0)
return -1;
return count_subset;
}
// Driver Code
public static void main(String args[])
{
int []arr = { 0, 0, 2, 1 };
int n = arr.length;
System.out.println(subsetCount(arr, n));
}
}
// This code is contributed by Samim Hossain Mondal.
Python3
# Python 3 implementation of the above approach
# Function to find the no of
# possible subsets
def subsetCount(arr, n):
# Count the no of 0s and 1s
# in array
zeros = 0
ones = 0
for i in range(n):
if (arr[i] == 0):
zeros += 1
elif (arr[i] == 1):
ones += 1
# Store no of ways to remove 0
no_of_ways_0 = pow(2, zeros)
# Store no of ways to remove 1
no_of_ways_1 = ones
# Store the total count of subsets
count_subset = no_of_ways_0 * no_of_ways_1
# If there is no subset possible
# with required sum, return -1
if (count_subset == 0):
return -1
return count_subset
# Driver Code
if __name__ == "__main__":
arr = [0, 0, 2, 1]
n = len(arr)
print(subsetCount(arr, n))
# This code is contributed by ukasp.
C#
// C# implementation of the above approach
using System;
class GFG
{
// Function to find the no of
// possible subsets
static int subsetCount(int []arr, int n)
{
// Count the no of 0s and 1s
// in array
int zeros = 0, ones = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == 0) {
zeros++;
}
else if (arr[i] == 1) {
ones++;
}
}
// Store no of ways to remove 0
int no_of_ways_0 = (int)Math.Pow(2, zeros);
// Store no of ways to remove 1
int no_of_ways_1 = ones;
// Store the total count of subsets
int count_subset = no_of_ways_0
* no_of_ways_1;
// If there is no subset possible
// with required sum, return -1
if (count_subset == 0)
return -1;
return count_subset;
}
// Driver Code
public static void Main()
{
int []arr = { 0, 0, 2, 1 };
int n = arr.Length;
Console.Write(subsetCount(arr, n));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
4
时间复杂度: O(n),其中 n = 数组长度
辅助空间:O(1)