给定两个长度分别为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
方法:这个问题可以通过动态规划解决。请按照以下步骤解决问题:
- 遍历字符串。
- 初始化一个二维数组dp[N][M] ,其中N是字符串str的长度, M是字符串X的长度。
- dp[i][j]表示子串str[0, i] 中所需的最小字符移除次数,使得子串X[0, j]作为子序列不出现。
- 两个过渡状态是:
- 如果str[i] 等于 X[j] ,
- 情况 1:删除字符str[i]
- 情况 2:通过确保没有出现X[0, j-1]作为str[0, i] 中的子序列来维护字符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.
Javascript
输出:
1
时间复杂度: O(N * M)
辅助空间: O(N * M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。