给定两个长度分别为N和M的字符串str和X ,任务是找到需要从字符串str中删除的最小字符,以使字符串str不包含字符串X作为子序列。
例子:
Input: str = “btagd”, X = “bad”
Output: 1
Explanation:
String “btag” has does not contain “bad” as a subsequence. Therefore, only one removal is required.
Input: str = “bbaaddd”, X = “bad”
Output: 2
方法:可以通过动态编程解决此问题。请按照以下步骤解决问题:
- 遍历字符串。
- 初始化2D数组dp [N] [M] ,其中N是字符串str的长度, M是字符串X的长度。
- dp [i] [j]表示子串str [0,i]中需要除去的最小字符数,这样就不会出现子串X [0,j]作为子序列。
- 这两个过渡状态是:
- 如果str [i]等于X [j] ,
- 情况1:删除字符str [i]
- 情况2:通过确保在str [0,i]中没有出现X [0,j-1]作为子序列来保持字符str [ i]
- 更新dp [i] [j] = min(dp [i-1] [j-1],dp [i-1] [j] +1)
- 如果str [i]不等于X [j],则str [i]可以保持不变。
- 更新dp [i] [j] = dp [i – 1] [j]
- 如果str [i]等于X [j] ,
- 打印最小清除量,即dp [N – 1] [M – 1]
下面是上述方法的实现:
C++
// C++ implementation of
// the above approach
#include
using namespace std;
// Function to print the minimum number of
// character removals required to remove X
// as a subsequence from the string str
void printMinimumRemovals(string str, string X)
{
// Length of the string str
int N = str.size();
// Length of the string X
int M = X.size();
// Stores the dp states
int dp[N][M] = {};
// Fill first row of dp[][]
for (int j = 0; j < M; j++) {
// If X[j] matches with str[0]
if (str[0] == X[j]) {
dp[0][j] = 1;
}
}
for (int i = 1; i < N; i++) {
for (int j = 0; j < M; j++) {
// If str[i] is equal to X[j]
if (str[i] == X[j]) {
// Update state after removing str[i[
dp[i][j] = dp[i - 1][j] + 1;
// Update state after keeping str[i]
if (j != 0)
dp[i][j]
= min(dp[i][j], dp[i - 1][j - 1]);
}
// If str[i] is not equal to X[j]
else {
dp[i][j] = dp[i - 1][j];
}
}
}
// Print the minimum number
// of characters removals
cout << dp[N - 1][M - 1];
}
// Driver Code
int main()
{
// Input
string str = "btagd";
string X = "bad";
// Function call to get minimum
// number of character removals
printMinimumRemovals(str, X);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
// Function to print the minimum number of
// character removals required to remove X
// as a subsequence from the string str
static void printMinimumRemovals(String str, String X)
{
// Length of the string str
int N = str.length();
// Length of the string X
int M = X.length();
// Stores the dp states
int dp[][] = new int[N][M];
// Fill first row of dp[][]
for (int j = 0; j < M; j++) {
// If X[j] matches with str[0]
if (str.charAt(0) == X.charAt(j)) {
dp[0][j] = 1;
}
}
for (int i = 1; i < N; i++) {
for (int j = 0; j < M; j++) {
// If str[i] is equal to X[j]
if (str.charAt(i) == X.charAt(j)) {
// Update state after removing str[i[
dp[i][j] = dp[i - 1][j] + 1;
// Update state after keeping str[i]
if (j != 0)
dp[i][j] = Math.min(
dp[i][j], dp[i - 1][j - 1]);
}
// If str[i] is not equal to X[j]
else {
dp[i][j] = dp[i - 1][j];
}
}
}
// Print the minimum number
// of characters removals
System.out.println(dp[N - 1][M - 1]);
}
// Driver code
public static void main(String[] args)
{
// Input
String str = "btagd";
String X = "bad";
// Function call to get minimum
// number of character removals
printMinimumRemovals(str, X);
}
}
// This code is contributed by Kingash.
Python3
# Python 3 implementation of
# the above approach
# Function to print the minimum number of
# character removals required to remove X
# as a subsequence from the string str
def printMinimumRemovals(s, X):
# Length of the string str
N = len(s)
# Length of the string X
M = len(X)
# Stores the dp states
dp = [[0 for x in range(M)] for y in range(N)]
# Fill first row of dp[][]
for j in range(M):
# If X[j] matches with str[0]
if (s[0] == X[j]):
dp[0][j] = 1
for i in range(1, N):
for j in range(M):
# If s[i] is equal to X[j]
if (s[i] == X[j]):
# Update state after removing str[i[
dp[i][j] = dp[i - 1][j] + 1
# Update state after keeping str[i]
if (j != 0):
dp[i][j] = min(dp[i][j], dp[i - 1][j - 1])
# If str[i] is not equal to X[j]
else:
dp[i][j] = dp[i - 1][j]
# Print the minimum number
# of characters removals
print(dp[N - 1][M - 1])
# Driver Code
if __name__ == "__main__":
# Input
s = "btagd"
X = "bad"
# Function call to get minimum
# number of character removals
printMinimumRemovals(s, X)
# This code is contributed by ukasp.
C#
// C# program for above approach
using System;
public class GFG
{
// Function to print the minimum number of
// character removals required to remove X
// as a subsequence from the string str
static void printMinimumRemovals(string str, string X)
{
// Length of the string str
int N = str.Length;
// Length of the string X
int M = X.Length;
// Stores the dp states
int[,] dp = new int[N, M];
// Fill first row of dp[][]
for (int j = 0; j < M; j++) {
// If X[j] matches with str[0]
if (str[0] == X[j]) {
dp[0, j] = 1;
}
}
for (int i = 1; i < N; i++) {
for (int j = 0; j < M; j++) {
// If str[i] is equal to X[j]
if (str[i] == X[j]) {
// Update state after removing str[i[
dp[i, j] = dp[i - 1, j] + 1;
// Update state after keeping str[i]
if (j != 0)
dp[i, j] = Math.Min(
dp[i, j], dp[i - 1, j - 1]);
}
// If str[i] is not equal to X[j]
else {
dp[i, j] = dp[i - 1, j];
}
}
}
// Print the minimum number
// of characters removals
Console.WriteLine(dp[N - 1, M - 1]);
}
// Driver code
public static void Main(String[] args)
{
// Input
string str = "btagd";
string X = "bad";
// Function call to get minimum
// number of character removals
printMinimumRemovals(str, X);
}
}
// This code is contributed by sanjoy_62.
输出:
1
时间复杂度: O(N * M)
辅助空间: O(N * M)