📌  相关文章
📜  可以用给定的零和一组成的最大字符串数

📅  最后修改于: 2021-09-17 07:18:04             🧑  作者: Mango

给定一个只有 0 和 1 的字符串arr[]和两个整数NM 的列表,其中N1 的数量, M0 的数量。任务是从给定的字符串列表中找到可以用给定数量的 0 和 1 构造的最大字符串数。

例子:

朴素的方法:这个想法是生成给定字符串列表的所有组合,并检查满足给定条件的零和一的计数。但是这个解决方案的时间复杂度是指数级的。

时间复杂度: O( 2 N ),其中N是列表中的字符串数。

有效的方法:
使用动态规划给出了一个有效的解决方案。这个想法是使用递归来生成所有可能的组合,并在递归期间存储重叠子问题的结果。

以下是步骤:

  • 这个想法是使用 3D dp 数组( dp[M][N][i] ),其中NM分别是10 的数量, i是列表中字符串的索引。
  • 查找当前字符串中10 的数量,并检查 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 现场工作专业课程学生竞争性编程现场课程