给定一个由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.
朴素的方法:请参阅本文的前一篇文章,了解解决问题的最简单方法。
时间复杂度: O(2 N )
辅助空间: O(1)
动态编程方法:有关动态编程方法,请参阅本文的前一篇文章。
时间复杂度: O(N*A*B)
辅助空间: O(N * A * B)
空间优化动态规划方法:上述方法中的空间复杂度可以基于以下观察进行优化:
- 初始化一个二维数组dp[A][B] ,其中dp[i][j]表示最长子集的长度,最多包含i个0 s 和j个1 s。
- 优化从3D表到2D表的辅助空间,思路是逆序遍历内部循环。
- 这确保无论何时dp[][] 中的值发生更改,在当前迭代中都不再需要它。
- 因此,递推关系如下所示:
dp[i][j] = max (dp[i][j], dp[i – zeros][j – ones] + 1)
where zeros is the count of 0s and ones is the count of 1s in the current iteration.
请按照以下步骤解决问题:
- 初始化一个二维数组,比如dp[A][B]并将其所有条目初始化为0 。
- 遍历给定的数组arr[]并对每个二进制字符串执行以下步骤:
- 将当前字符串中 0 和 1 的计数分别存储在变量0和1 中。
- 迭代在范围[A,零]使用同时迭代在范围[B,那些]使用变量j和更新到最大DP的DP [i] [j]的值的变量i和[I] [j]的和(dp[i – zeros][j –ones] + 1) 。
- 完成以上步骤后,打印dp[A][B]的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// 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)
{
// Initialize a 2D array with its
// entries as 0
int dp[A + 1][B + 1];
memset(dp, 0, sizeof(dp));
// Traverse the given array
for (auto& str : arr) {
// Store the count of 0s and 1s
// in the current string
int zeros = count(str.begin(),
str.end(), '0');
int ones = count(str.begin(),
str.end(), '1');
// Iterate in the range [A, zeros]
for (int i = A; i >= zeros; i--)
// Iterate in the range [B, ones]
for (int j = B; j >= ones; j--)
// Update the value of dp[i][j]
dp[i][j] = max(
dp[i][j],
dp[i - zeros][j - ones] + 1);
}
// Print the result
return dp[A][B];
}
// Driver Code
int main()
{
vector arr
= { "1", "0", "0001",
"10", "111001" };
int A = 5, B = 3;
cout << MaxSubsetlength(arr, A, B);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// Function to find the length of the
// longest subset of an array of strings
// with at most A 0s and B 1s
static int MaxSubsetlength(String arr[],
int A, int B)
{
// Initialize a 2D array with its
// entries as 0
int dp[][] = new int[A + 1][B + 1];
// Traverse the given array
for(String str : arr)
{
// Store the count of 0s and 1s
// in the current string
int zeros = 0, ones = 0;
for(char ch : str.toCharArray())
{
if (ch == '0')
zeros++;
else
ones++;
}
// Iterate in the range [A, zeros]
for(int i = A; i >= zeros; i--)
// Iterate in the range [B, ones]
for(int j = B; j >= ones; j--)
// Update the value of dp[i][j]
dp[i][j] = Math.max(
dp[i][j],
dp[i - zeros][j - ones] + 1);
}
// Print the result
return dp[A][B];
}
// Driver Code
public static void main(String[] args)
{
String arr[] = { "1", "0", "0001",
"10", "111001" };
int A = 5, B = 3;
System.out.println(MaxSubsetlength(arr, A, B));
}
}
// This code is contributed by Kingash
Python3
# Python3 program for the above approach
# Function to find the length of the
# longest subset of an array of strings
# with at most A 0s and B 1s
def MaxSubsetlength(arr, A, B):
# Initialize a 2D array with its
# entries as 0
dp = [[0 for i in range(B + 1)]
for i in range(A + 1)]
# Traverse the given array
for str in arr:
# Store the count of 0s and 1s
# in the current string
zeros = str.count('0')
ones = str.count('1')
# Iterate in the range [A, zeros]
for i in range(A, zeros - 1, -1):
# Iterate in the range [B, ones]
for j in range(B, ones - 1, -1):
# Update the value of dp[i][j]
dp[i][j] = max(dp[i][j],
dp[i - zeros][j - ones] + 1)
# Print the result
return dp[A][B]
# Driver Code
if __name__ == '__main__':
arr = [ "1", "0", "0001", "10", "111001" ]
A, B = 5, 3
print (MaxSubsetlength(arr, A, B))
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG {
// Function to find the length of the
// longest subset of an array of strings
// with at most A 0s and B 1s
static int MaxSubsetlength(string[] arr, int A, int B)
{
// Initialize a 2D array with its
// entries as 0
int[, ] dp = new int[A + 1, B + 1];
// Traverse the given array
foreach(string str in arr)
{
// Store the count of 0s and 1s
// in the current string
int zeros = 0, ones = 0;
foreach(char ch in str.ToCharArray())
{
if (ch == '0')
zeros++;
else
ones++;
}
// Iterate in the range [A, zeros]
for (int i = A; i >= zeros; i--)
// Iterate in the range [B, ones]
for (int j = B; j >= ones; j--)
// Update the value of dp[i][j]
dp[i, j] = Math.Max(
dp[i, j],
dp[i - zeros, j - ones] + 1);
}
// Print the result
return dp[A, B];
}
// Driver Code
public static void Main(string[] args)
{
string[] arr = { "1", "0", "0001", "10", "111001" };
int A = 5, B = 3;
Console.WriteLine(MaxSubsetlength(arr, A, B));
}
}
// This code is contributed by ukasp.
Javascript
4
时间复杂度: O(N * A * B)
辅助空间: O(A * B)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。