📌  相关文章
📜  字符串数组中由A 0和B 1组成的最长子集的长度

📅  最后修改于: 2021-04-17 19:12:37             🧑  作者: Mango

给定一个数组arr [] ,该数组由N个二进制字符串以及两个整数AB组成,任务是 求出最多由A 0 s和B 1 s组成的最长子集的长度。

例子:

天真的方法:解决上述问题的最简单方法是使用递归。在每个递归调用中,其想法是包括或排除当前字符串。一旦考虑了所有可能性,请打印获得的最大子集长度。

下面是上述方法的实现:

C++14
// C++ program for the above approach
#include 
using namespace std;
 
// Function to count 0's in a string
int count0(string s)
{
    // Stores count of 0s
    int count = 0;
 
    // Iterate over characters of string
    for (int i = 0; i < s.size(); i++) {
 
        // If current character is '0'
        if (s[i] == '0') {
            count++;
        }
    }
    return count;
}
 
// Recursive function to find the length of
// longest subset from an array of strings
// with at most A 0's and B 1's
int solve(vector vec,
          int A, int B, int idx)
{
    // If idx is equal to N
    // or A + B is equal to 0
    if (idx == vec.size() || A + B == 0) {
        return 0;
    }
 
    // Stores the count of 0's in arr[idx]
    int zero = count0(vec[idx]);
 
    // Stores the count of 1's in arr[idx]
    int one = vec[idx].size() - zero;
 
    // Stores the length of the
    // subset if arr[i] is included
    int inc = 0;
 
    // If zero is less than or equal to A
    // and one is less than or equal to B
    if (zero <= A && one <= B) {
        inc = 1 + solve(vec, A - zero,
                        B - one, idx + 1);
    }
 
    // Stores the length of the subset
    // if arr[i] is excluded
    int exc = solve(vec, A, B, idx + 1);
 
    // Returns max of inc and exc
    return max(inc, exc);
}
 
// Function to find the length of the
// longest subset from an array of
// strings with at most A 0's and B 1's
int MaxSubsetlength(vector arr,
                    int A, int B)
{
    // Return
    return solve(arr, A, B, 0);
}
 
// Driver Code
int main()
{
    vector arr = { "1", "0", "10" };
    int A = 1, B = 1;
 
    cout << MaxSubsetlength(arr, A, B);
    return 0;
}


Python3
# Python3 program for the above approach
 
# Function to count 0's in a string
def count0(s):
     
    # Stores count of 0s
    count = 0
 
    # Iterate over characters of string
    for i in range(len(s)):
         
        # If current character is '0'
        if (s[i] == '0'):
            count += 1
             
    return count
 
# Recursive function to find the length of
# longest subset from an array of strings
# with at most A 0's and B 1's
def solve(vec, A, B, idx):
     
    # If idx is equal to N
    # or A + B is equal to 0
    if (idx == len(vec) or A + B == 0):
        return 0
 
    # Stores the count of 0's in arr[idx]
    zero = count0(vec[idx])
 
    # Stores the count of 1's in arr[idx]
    one = len(vec[idx]) - zero
 
    # Stores the length of the
    # subset if arr[i] is included
    inc = 0
 
    # If zero is less than or equal to A
    # and one is less than or equal to B
    if (zero <= A and one <= B):
        inc = 1 + solve(vec, A - zero,
                             B - one, idx + 1)
 
    # Stores the length of the subset
    # if arr[i] is excluded
    exc = solve(vec, A, B, idx + 1)
 
    # Returns max of inc and exc
    return max(inc, exc)
 
# Function to find the length of the
# longest subset from an array of
# strings with at most A 0's and B 1's
def MaxSubsetlength(arr, A, B):
     
    # Return
    return solve(arr, A, B, 0)
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ "1", "0", "10" ]
    A = 1
    B = 1
     
    print(MaxSubsetlength(arr, A, B))
 
# This code is contributed by SURENDRA_GANGWAR


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to count 0's in a string
static int count0(string s)
{
     
    // Stores count of 0s
    int count = 0;
 
    // Iterate over characters of string
    for(int i = 0; i < s.Length; i++)
    {
         
        // If current character is '0'
        if (s[i] == '0')
        {
            count++;
        }
    }
    return count;
}
 
// Recursive function to find the length of
// longest subset from an array of strings
// with at most A 0's and B 1's
static int solve(List vec, int A, int B,
                 int idx)
{
     
    // If idx is equal to N
    // or A + B is equal to 0
    if (idx == vec.Count || A + B == 0)
    {
        return 0;
    }
 
    // Stores the count of 0's in arr[idx]
    int zero = count0(vec[idx]);
 
    // Stores the count of 1's in arr[idx]
    int one = vec[idx].Length - zero;
 
    // Stores the length of the
    // subset if arr[i] is included
    int inc = 0;
 
    // If zero is less than or equal to A
    // and one is less than or equal to B
    if (zero <= A && one <= B)
    {
        inc = 1 + solve(vec, A - zero,
                             B - one, idx + 1);
    }
 
    // Stores the length of the subset
    // if arr[i] is excluded
    int exc = solve(vec, A, B, idx + 1);
 
    // Returns max of inc and exc
    return Math.Max(inc, exc);
}
 
// Function to find the length of the
// longest subset from an array of
// strings with at most A 0's and B 1's
static int MaxSubsetlength(List arr, int A,
                           int B)
{
     
    // Return
    return solve(arr, A, B, 0);
}
 
// Driver Code
public static void Main()
{
    List arr = new List{ "1", "0", "10" };
    int A = 1, B = 1;
 
    Console.WriteLine(MaxSubsetlength(arr, A, B));
}
}
 
// This code is contributed by ukasp


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to count number
// of 0s present in the string
int count0(string s)
{
    // Stores the count of 0s
    int count = 0;
 
    // Iterate over characters of string
    for (int i = 0; i < s.size(); i++) {
 
        // If current character is '0'
        if (s[i] == '0') {
            count++;
        }
    }
    return count;
}
// Recursive Function to find the length of
// longest subset from given array of strings
// with at most A 0s and B 1s
int solve(vector vec, int A,
          int B, int idx,
          vector > >& dp)
{
    // If idx is equal to N or
    // A + B is equal to 0
    if (idx == vec.size() || A + B == 0) {
        return 0;
    }
    // If the state is already calculated
    if (dp[A][B][idx] > 0) {
        return dp[A][B][idx];
    }
 
    // Stores the count of 0's
    int zero = count0(vec[idx]);
 
    // Stores the count of 1's
    int one = vec[idx].size() - zero;
 
    // Stores the length of longest
    // by including arr[idx]
    int inc = 0;
 
    // If zero is less than A
    // and one is less than B
    if (zero <= A && one <= B) {
        inc = 1
              + solve(vec, A - zero,
                      B - one, idx + 1, dp);
    }
 
    // Stores the length of longest subset
    // by excluding arr[idx]
    int exc = solve(vec, A, B, idx + 1, dp);
 
    // Assign
    dp[A][B][idx] = max(inc, exc);
 
    // Return
    return dp[A][B][idx];
}
 
// Function to find the length of the
// longest subset of an array of strings
// with at most A 0s and B 1s
int MaxSubsetlength(vector arr,
                    int A, int B)
{
    // Stores all Dp-states
    vector > > dp(
        A + 1,
        vector >(B + 1,
                             vector(arr.size() + 1,
                                         0)));
    // Return
    return solve(arr, A, B, 0, dp);
}
 
// Driver Code
int main()
{
    vector arr = { "1", "0", "10" };
    int A = 1, B = 1;
 
    cout << MaxSubsetlength(arr, A, B);
    return 0;
}


输出:
2

时间复杂度: O(2 N )
辅助空间: O(1)

高效的方法:基于以下观察,可以使用“记忆化”来优化上述方法:

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Function to count number
// of 0s present in the string
int count0(string s)
{
    // Stores the count of 0s
    int count = 0;
 
    // Iterate over characters of string
    for (int i = 0; i < s.size(); i++) {
 
        // If current character is '0'
        if (s[i] == '0') {
            count++;
        }
    }
    return count;
}
// Recursive Function to find the length of
// longest subset from given array of strings
// with at most A 0s and B 1s
int solve(vector vec, int A,
          int B, int idx,
          vector > >& dp)
{
    // If idx is equal to N or
    // A + B is equal to 0
    if (idx == vec.size() || A + B == 0) {
        return 0;
    }
    // If the state is already calculated
    if (dp[A][B][idx] > 0) {
        return dp[A][B][idx];
    }
 
    // Stores the count of 0's
    int zero = count0(vec[idx]);
 
    // Stores the count of 1's
    int one = vec[idx].size() - zero;
 
    // Stores the length of longest
    // by including arr[idx]
    int inc = 0;
 
    // If zero is less than A
    // and one is less than B
    if (zero <= A && one <= B) {
        inc = 1
              + solve(vec, A - zero,
                      B - one, idx + 1, dp);
    }
 
    // Stores the length of longest subset
    // by excluding arr[idx]
    int exc = solve(vec, A, B, idx + 1, dp);
 
    // Assign
    dp[A][B][idx] = max(inc, exc);
 
    // Return
    return dp[A][B][idx];
}
 
// Function to find the length of the
// longest subset of an array of strings
// with at most A 0s and B 1s
int MaxSubsetlength(vector arr,
                    int A, int B)
{
    // Stores all Dp-states
    vector > > dp(
        A + 1,
        vector >(B + 1,
                             vector(arr.size() + 1,
                                         0)));
    // Return
    return solve(arr, A, B, 0, dp);
}
 
// Driver Code
int main()
{
    vector arr = { "1", "0", "10" };
    int A = 1, B = 1;
 
    cout << MaxSubsetlength(arr, A, B);
    return 0;
}
输出:
2

时间复杂度: O(N * A * B)
辅助空间: O(N * A * B)