通过替换通配符“?”形成的非递减数字字符串的计数
给定一个大小为N的字符串S ,由数字和? ,任务是找到形成的字符串的数量,以便替换字符“?”使用任何数字,使字符串的数字变为非递减。
例子:
Input: S = “1???2”
Output: 4
Explanation:
The string after valid replacements of ‘?’ is 11112, 11122, 11222, 12222. Therefore, the count of such string is 1.
Input: S = “2??43?4”
Output: 0
方法:给定的问题可以通过替换“?”来解决使用递归所有可能的有效数字组合并将重叠子问题存储在dp[]表中。请按照以下步骤解决给定的问题:
- 初始化一个二维数组,比如dp[][] ,这样dp[i][j]将表示长度为 i且位于端点差为 j的两个数字之间的有效字符串的可能数量。由于不同的段包含?彼此独立。因此,总计数将是每个段可用的所有选项的乘积。
- 将dp[][]初始化为 -1。
- 将三个变量L声明为0 , R为9 , cnt ,使得L表示段的左边界, R表示段的右边界, cnt表示连续'?'的长度字符。
- 让总计数存储在变量中,例如ans为1 。
- 定义一个函数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)