给定一个由N 个二进制字符串和两个整数A和B组成的数组arr[] ,任务是 找到最多由A 0 s 和B 1 s 组成的最长子集的长度。
例子:
Input: arr[] = {“1”, “0”, “0001”, “10”, “111001”}, A = 5, B = 3
Output: 4
Explanation:
One possible way is to select the subset {arr[0], arr[1], arr[2], arr[3]}.
Total number of 0s and 1s in all these strings are 5 and 3 respectively.
Also, 4 is the length of the longest subset possible.
Input: arr[] = {“0”, “1”, “10”}, A = 1, B = 1
Output: 2
Explanation:
One possible way is to select the subset {arr[0], arr[1]}.
Total number of 0s and 1s in all these strings is 1 and 1 respectively.
Also, 2 is the length of the longest subset possible.
朴素的方法:解决上述问题最简单的方法是使用递归。在每次递归调用时,想法是包含或排除当前字符串。一旦考虑了所有的可能性,打印得到的子集的最大长度。
下面是上述方法的实现:
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;
}
Java
// Java program for the above approach
import java.util.*;
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.charAt(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(String[] vec,
int A, int B, int idx)
{
// If idx is equal to N
// or A + B is equal to 0
if (idx == vec.length || 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(String[] arr,
int A, int B)
{
// Return
return solve(arr, A, B, 0);
}
public static void main (String[] args) {
String[] arr = { "1", "0", "10" };
int A = 1, B = 1;
System.out.print(MaxSubsetlength(arr, A, B));
}
}
// This code is contributed by offbeat
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
Javascript
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)
高效方法:基于以下观察,可以使用 Memoization 优化上述方法:
- It can be observed that there exists a overlapping subproblem and optimal substructure property.
Therefore, the idea is to use dynamic programming to optimize the above approach. - The idea is to use the 3D-state dynamic programming.
- Suppose Dp(i, A, B) represents the maximum length of the subset with at most A 0s and B 1s.
- Then the transition of states can be defined by either selecting a string at ith index or not,
- Dp(i, A, B) = Max(1+Dp(i+1, A- Z, B-O), Dp(i+1, A, B)),
where Z is the count of Os and O is the count of 0s.
- Dp(i, A, B) = Max(1+Dp(i+1, A- Z, B-O), Dp(i+1, A, B)),
下面是上述方法的实现:
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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live