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

📅  最后修改于: 2021-04-22 04:02:18             🧑  作者: Mango

给定一个仅由零和一组成的字符串arr []以及两个整数NM ,其中N1的数量, M0的数量。任务是从给定的0和1的给定字符串列表中找到最大字符串数。

例子:

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

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

高效方法:
通过使用动态编程给出了一种有效的解决方案。想法是使用递归生成所有可能的组合,并在递归期间存储“重叠子问题”的结果。
步骤如下:

  1. 这个想法是使用3D dp数组( dp [M] [N] [i] ),其中NM分别是10的数量,而i是列表中字符串的索引。
  2. 在当前字符串找到10的数目,并检查零和一的计数分别小于或等于给定的计数N和M。
  3. 如果上述条件成立,则检查当前状态值是否存储在dp表中。如果是,则返回此值。
  4. 否则,通过将当前字符串包括和排除为以下内容,以递归方式进行下一次迭代:
    // 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)
    
  5. 以上两个递归调用的最大值将给出当前状态的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];
    }
  
    // Intialise 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;
  
    // Intialise 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];
    }
   
    // Intialise 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;
   
    // Intialise 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


Python 3
# 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]
  
    # Intialise 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];
    }
    
    // Intialise 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;
    
    // Intialise 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


输出:
4