📌  相关文章
📜  总和小于 Array 总和的子集计数

📅  最后修改于: 2022-05-13 01:57:53.114000             🧑  作者: Mango

总和小于 Array 总和的子集计数

给定一个大小为N的数组arr[ ] 。任务是数组中出现 0 时找到总和为 ( 数组的总和- 1 ) 的子集数,如果没有子集可能,则返回 -1。

例子:

朴素方法:该任务可以通过使用递归生成数组的所有可能子集来解决,如果遇到总和为(数组之和 - 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)