📜  通过替换通配符“?”形成的非递减数字字符串的计数

📅  最后修改于: 2022-05-13 01:56:04.370000             🧑  作者: Mango

通过替换通配符“?”形成的非递减数字字符串的计数

给定一个大小为N的字符串S ,由数字和? ,任务是找到形成的字符串的数量,以便替换字符“?”使用任何数字,使字符串的数字变为非递减。

例子:

方法:给定的问题可以通过替换“?”来解决使用递归所有可能的有效数字组合并将重叠子问题存储在dp[]表中。请按照以下步骤解决给定的问题:

  • 初始化一个二维数组,比如dp[][] ,这样dp[i][j]将表示长度为 i且位于端点差为 j的两个数字之间的有效字符串的可能数量。由于不同的段包含?彼此独立。因此,总计数将是每个段可用的所有选项的乘积。
  • dp[][]初始化为 -1。
  • 将三个变量L声明为0R9cnt ,使得L表示段的左边界, R表示段的右边界, cnt表示连续'?'的长度字符。
  • 让总计数存储在变量中,例如ans1
  • 定义一个函数solve ,它将递归地计算dp节点的值。求解函数将采用两个参数(len, gap) ,len 将表示连续“?”的总长度并且间隙将表示该段端点之间的差异:
    • 迭代每个可能的差距并使用solve(len – 1, gap – i)重新计算答案。
    • 填充节点dp[len][gap]后,返回从求解函数获得的答案。
  • 遍历字符串中的每个字符并执行以下步骤:
    • 如果当前字符是'?'然后递增变量cnt
    • 如果当前字符不是数字,则将右限制,即R更改为当前字符,即R = S[i] – '0'
    • 乘以递归函数solve(cnt, R – L)计算的答案。
  • 完成上述步骤后,打印ans的值作为形成的字符串的结果计数。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
#define MAXN 100005
 
// Define the dp table globally
int dp[MAXN][10];
 
// Recursive function to calculate total
// number of valid non-decreasing strings
int solve(int len, int gap)
{
    // If already calculated state
    if (dp[len][gap] != -1) {
        return dp[len][gap];
    }
 
    // Base Case
    if (len == 0 || gap == 0) {
        return 1;
    }
    if (gap < 0) {
        return 0;
    }
 
    // Stores the total count of strings
    // formed
    int ans = 0;
 
    for (int i = 0; i <= gap; i++) {
        ans += solve(len - 1, gap - i);
    }
 
    // Fill the value in dp matrix
    return dp[len][gap] = ans;
}
 
// Function to find the total number of
// non-decreasing string formed by
// replacing the '?'
int countValidStrings(string S)
{
    // Initialize all value of dp
    // table with -1
    memset(dp, -1, sizeof(dp));
 
    int N = S.length();
 
    // Left and Right limits
    int L = 1, R = 9;
 
    int cnt = 0;
    int ans = 1;
 
    // Iterate through all the characters
    // of the string S
    for (int i = 0; i < N; i++) {
 
        if (S[i] != '?') {
 
            // Change R to the current
            // character
            R = S[i] - '0';
 
            // Call the recursive function
            ans *= solve(cnt, R - L);
 
            // Change L to R and R to 9
            L = R;
            R = 9;
 
            // Reinitialize the length
            // of ? to 0
            cnt = 0;
        }
        else {
 
            // Increment the length of
            // the segment
            cnt++;
        }
    }
 
    // Update the ans
    ans *= solve(cnt, R - L);
 
    // Return the total count
    return ans;
}
 
// Driver Code
int main()
{
    string S = "1???2";
    cout << countValidStrings(S);
 
    return 0;
}


Java
// Java program for the above approach
 
import java.io.*;
 
class GFG {
 
    static final int MAXN = 100005;
 
    // Define the dp table globally
    static final int dp[][] = new int[MAXN][10];
 
    // Recursive function to calculate total
    // number of valid non-decreasing strings
    static int solve(int len, int gap)
    {
        // If already calculated state
        if (dp[len][gap] != -1) {
            return dp[len][gap];
        }
 
        // Base Case
        if (len == 0 || gap == 0) {
            return 1;
        }
        if (gap < 0) {
            return 0;
        }
 
        // Stores the total count of strings
        // formed
        int ans = 0;
 
        for (int i = 0; i <= gap; i++) {
            ans += solve(len - 1, gap - i);
        }
 
        // Fill the value in dp matrix
        return dp[len][gap] = ans;
    }
 
    // Function to find the total number of
    // non-decreasing string formed by
    // replacing the '?'
    static int countValidStrings(String S)
    {
        // Initialize all value of dp
        // table with -1
        for (int i = 0; i < MAXN; i++) {
            for (int j = 0; j < 10; j++) {
                dp[i][j] = -1;
            }
        }
 
        int N = S.length();
 
        // Left and Right limits
        int L = 1, R = 9;
 
        int cnt = 0;
        int ans = 1;
 
        // Iterate through all the characters
        // of the string S
        for (int i = 0; i < N; i++) {
     
            if (S.charAt(i) != '?') {
 
                // Change R to the current
                // character
                R = S.charAt(i) - '0';
 
                // Call the recursive function
                ans *= solve(cnt, R - L);
 
                // Change L to R and R to 9
                L = R;
                R = 9;
 
                // Reinitialize the length
                // of ? to 0
                cnt = 0;
            }
            else {
 
                // Increment the length of
                // the segment
                cnt++;
            }
        }
 
        // Update the ans
        ans *= solve(cnt, R - L);
 
        // Return the total count
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String S = "1???2";
        System.out.println(countValidStrings(S));
    }
}
 
// This code is contributed by Dharanendra L V.


Python3
# Python 3 program for the above approach
 
MAXN = 100005
 
# Define the dp table globally
dp = [[-1 for x in range(10)] for y in range(MAXN)]
 
# Recursive function to calculate total
# number of valid non-decreasing strings
def solve(len, gap):
 
    # If already calculated state
    if (dp[len][gap] != -1):
        return dp[len][gap]
 
    # Base Case
    if (len == 0 or gap == 0):
        return 1
 
    if (gap < 0):
        return 0
 
    # Stores the total count of strings
    # formed
    ans = 0
 
    for i in range(gap + 1):
        ans += solve(len - 1, gap - i)
 
    # Fill the value in dp matrix
    dp[len][gap] = ans
    return dp[len][gap]
 
# Function to find the total number of
# non-decreasing string formed by
# replacing the '?'
 
 
def countValidStrings(S):
 
    # Initialize all value of dp
    # table with -1
    global dp
 
    N = len(S)
 
    # Left and Right limits
    L, R = 1, 9
 
    cnt = 0
    ans = 1
 
    # Iterate through all the characters
    # of the string S
    for i in range(N):
 
        if (S[i] != '?'):
 
            # Change R to the current
            # character
            R = ord(S[i]) - ord('0')
 
            # Call the recursive function
            ans *= solve(cnt, R - L)
 
            # Change L to R and R to 9
            L = R
            R = 9
 
            # Reinitialize the length
            # of ? to 0
            cnt = 0
 
        else:
 
            # Increment the length of
            # the segment
            cnt += 1
 
    # Update the ans
    ans *= solve(cnt, R - L)
 
    # Return the total count
    return ans
 
 
# Driver Code
if __name__ == "__main__":
 
    S = "1???2"
    print(countValidStrings(S))
 
    # This code is contributed by ukasp.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
static int MAXN  = 100005;
 
// Define the dp table globally
static int [,]dp = new int[MAXN, 10];
 
// Recursive function to calculate total
// number of valid non-decreasing strings
static int solve(int len, int gap)
{
    // If already calculated state
    if (dp[len,gap] != -1) {
        return dp[len,gap];
    }
 
    // Base Case
    if (len == 0 || gap == 0) {
        return 1;
    }
    if (gap < 0) {
        return 0;
    }
 
    // Stores the total count of strings
    // formed
    int ans = 0;
 
    for (int i = 0; i <= gap; i++) {
        ans += solve(len - 1, gap - i);
    }
 
    // Fill the value in dp matrix
    return dp[len,gap] = ans;
}
 
// Function to find the total number of
// non-decreasing string formed by
// replacing the '?'
static int countValidStrings(string S)
{
   
    // Initialize all value of dp
    // table with -1
    for(int i = 0; i < MAXN; i++){
        for(int j = 0; j < 10; j++){
            dp[i, j] = -1;
        }
    }
     
    int N = S.Length;
 
    // Left and Right limits
    int L = 1, R = 9;
 
    int cnt = 0;
    int ans = 1;
 
    // Iterate through all the characters
    // of the string S
    for (int i = 0; i < N; i++) {
 
        if (S[i] != '?') {
 
            // Change R to the current
            // character
            R = (int)S[i] - 48;
 
            // Call the recursive function
            ans *= solve(cnt, R - L);
 
            // Change L to R and R to 9
            L = R;
            R = 9;
 
            // Reinitialize the length
            // of ? to 0
            cnt = 0;
        }
        else {
 
            // Increment the length of
            // the segment
            cnt++;
        }
    }
 
    // Update the ans
    ans *= solve(cnt, R - L);
 
    // Return the total count
    return ans;
}
 
// Driver Code
public static void Main()
{
    string S = "1???2";
    Console.Write(countValidStrings(S));
}
}
 
// This code is contributed by SURENDR_GANGWAR.


Javascript


输出:
4

时间复杂度: O(N*10)
辅助空间: O(N*10)