给定一个只有 0 和 1 的字符串arr[]和两个整数N和M 的列表,其中N是1 的数量, M是0 的数量。任务是从给定的字符串列表中找到可以用给定数量的 0 和 1 构造的最大字符串数。
例子:
Input: arr[] = {“10”, “0001”, “11100”, “1”, “0”}, M = 5, N = 3
Output: 4
Explanation:
The 4 strings which can be formed using five 0’s and three 1’s are: “10”, “0001”, “1”, “0”
Input: arr[] = {“10”, “00”, “000” “0001”, “111001”, “1”, “0”}, M = 3, N = 1
Output: 3
Explanation:
The 3 strings which can be formed using three 0’s and one 1’s are: “00”, “1”, “0”
朴素的方法:这个想法是生成给定字符串列表的所有组合,并检查满足给定条件的零和一的计数。但是这个解决方案的时间复杂度是指数级的。
时间复杂度: O( 2 N ),其中N是列表中的字符串数。
有效的方法:
使用动态规划给出了一个有效的解决方案。这个想法是使用递归来生成所有可能的组合,并在递归期间存储重叠子问题的结果。
以下是步骤:
- 这个想法是使用 3D dp 数组( dp[M][N][i] ),其中N和M分别是1和0 的数量, i是列表中字符串的索引。
- 查找当前字符串中1和0 的数量,并检查 0 和 1 的计数是否分别小于或等于给定的计数N 和 M。
- 如果上述条件为真,则检查当前状态值是否存储在 dp 表中。如果是,则返回此值。
- 否则通过包含和排除当前字符串为下一次迭代递归移动:
// By including the current string
x = 1 + recursive_function(M - zero, N - ones, arr, i + 1)
// By excluding the current string
y = recursive_function(M, N, arr, i + 1)
// and update the dp table as:
dp[M][N][i] = max(x, y)
- 上述两个递归调用的最大值将给出当前状态的最大数目,其中N 1 和 M 0 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// 3D dp table to store the state value
int dp[100][100][100];
// Function that count the combination
// of 0's and 1's from the given list
// of string
int countString(int m, int n,
vector& arr, int i)
{
// Base Case if count of 0's or 1's
// becomes negative
if (m < 0 || n < 0) {
return INT_MIN;
}
// If index reaches out of bound
if (i >= arr.size()) {
return 0;
}
// Return the prestored result
if (dp[m][n][i] != -1) {
return dp[m][n][i];
}
// Initialize count of 0's and 1's
// to 0 for the current state
int zero = 0, one = 0;
// Calculate the number of 1's and
// 0's in current string
for (char c : arr[i]) {
if (c == '0') {
zero++;
}
else {
one++;
}
}
// Include the current string and
// recurr for the next iteration
int x = 1 + countString(m - zero,
n - one,
arr, i + 1);
// Exclude the current string and
// recurr for the next iteration
int y = countString(m, n, arr, i + 1);
// Update the maximum of the above
// two states to the current dp state
return dp[m][n][i] = max(x, y);
}
// Driver Code
int main()
{
vector arr = { "10", "0001", "1",
"111001", "0" };
// N 0's and M 1's
int N = 3, M = 5;
// Initialize dp array to -1
memset(dp, -1, sizeof(dp));
// Function call
cout << countString(M, N, arr, 0);
}
Java
// Java program for the above approach
class GFG{
// 3D dp table to store the state value
static int [][][]dp = new int[100][100][100];
// Function that count the combination
// of 0's and 1's from the given list
// of String
static int countString(int m, int n,
String []arr, int i)
{
// Base Case if count of 0's or 1's
// becomes negative
if (m < 0 || n < 0) {
return Integer.MIN_VALUE;
}
// If index reaches out of bound
if (i >= arr.length) {
return 0;
}
// Return the prestored result
if (dp[m][n][i] != -1) {
return dp[m][n][i];
}
// Initialize count of 0's and 1's
// to 0 for the current state
int zero = 0, one = 0;
// Calculate the number of 1's and
// 0's in current String
for (char c : arr[i].toCharArray()) {
if (c == '0') {
zero++;
}
else {
one++;
}
}
// Include the current String and
// recurr for the next iteration
int x = 1 + countString(m - zero,
n - one,
arr, i + 1);
// Exclude the current String and
// recurr for the next iteration
int y = countString(m, n, arr, i + 1);
// Update the maximum of the above
// two states to the current dp state
return dp[m][n][i] = Math.max(x, y);
}
// Driver Code
public static void main(String[] args)
{
String []arr = { "10", "0001", "1",
"111001", "0" };
// N 0's and M 1's
int N = 3, M = 5;
// Initialize dp array to -1
for(int i = 0;i<100;i++){
for(int j = 0;j<100;j++){
for(int l=0;l<100;l++)
dp[i][j][l]=-1;
}
}
// Function call
System.out.print(countString(M, N, arr, 0));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python 3 program for the above approach
import sys
# 3D dp table to store the state value
dp = [[[-1 for i in range(100)]for j in range(100)] for k in range(100)]
# Function that count the combination
# of 0's and 1's from the given list
# of string
def countString(m, n, arr, i):
# Base Case if count of 0's or 1's
# becomes negative
if (m < 0 or n < 0):
return -sys.maxsize - 1
# If index reaches out of bound
if (i >= len(arr)):
return 0
# Return the prestored result
if (dp[m][n][i] != -1):
return dp[m][n][i]
# Initialize count of 0's and 1's
# to 0 for the current state
zero = 0
one = 0
# Calculate the number of 1's and
# 0's in current string
for c in arr[i]:
if (c == '0'):
zero += 1
else:
one += 1
# Include the current string and
# recurr for the next iteration
x = 1 + countString(m - zero, n - one, arr, i + 1)
# Exclude the current string and
# recurr for the next iteration
y = countString(m, n, arr, i + 1)
dp[m][n][i] = max(x, y)
# Update the maximum of the above
# two states to the current dp state
return dp[m][n][i]
# Driver Code
if __name__ == '__main__':
arr = ["10", "0001", "1","111001", "0"]
# N 0's and M 1's
N = 3
M = 5
# Function call
print(countString(M, N, arr, 0))
# This code is contributed by Surendra_Gangwar
C#
// C# program for the above approach
using System;
class GFG{
// 3D dp table to store the state value
static int [,,]dp = new int[100, 100, 100];
// Function that count the combination
// of 0's and 1's from the given list
// of String
static int countString(int m, int n,
String []arr, int i)
{
// Base Case if count of 0's or 1's
// becomes negative
if (m < 0 || n < 0) {
return int.MinValue;
}
// If index reaches out of bound
if (i >= arr.Length) {
return 0;
}
// Return the prestored result
if (dp[m, n, i] != -1) {
return dp[m, n, i];
}
// Initialize count of 0's and 1's
// to 0 for the current state
int zero = 0, one = 0;
// Calculate the number of 1's and
// 0's in current String
foreach (char c in arr[i].ToCharArray()) {
if (c == '0') {
zero++;
}
else {
one++;
}
}
// Include the current String and
// recurr for the next iteration
int x = 1 + countString(m - zero,
n - one,
arr, i + 1);
// Exclude the current String and
// recurr for the next iteration
int y = countString(m, n, arr, i + 1);
// Update the maximum of the above
// two states to the current dp state
return dp[m, n, i] = Math.Max(x, y);
}
// Driver Code
public static void Main(String[] args)
{
String []arr = { "10", "0001", "1",
"111001", "0" };
// N 0's and M 1's
int N = 3, M = 5;
// Initialize dp array to -1
for(int i = 0; i < 100; i++){
for(int j = 0; j < 100; j++){
for(int l = 0; l < 100; l++)
dp[i, j, l] = -1;
}
}
// Function call
Console.Write(countString(M, N, arr, 0));
}
}
// This code is contributed by Rajput-Ji
Javascript
4
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。