Minimize removals to remove another string as a subsequence of a given string

Given two strings str and X of length N and M respectively, the task is to find the minimum characters required to be removed from the string str such that string str doesn’t contain the string X as a subsequence.
Examples:
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
Approach: This problem can be solved by Dynamic Programming. Follow the steps below to solve the problem:
- Traverse the string.
- Initialize a 2D array dp[N][M], where N is the length of string str and M is the length of string X.
- dp[i][j] represents the minimum number of character removal required in the substring str[0, i] such that there is no occurrence of substring X[0, j] as a subsequence.
- The two transition states are:
- If str[i] is equal to X[j],
- Case 1: Remove the character str[i]
- Case 2: Maintain the character str[i], by ensuring that there is no occurrence of X[0, j-1] as a subsequence in str[0, i]
- Update dp[i][j] = min(dp[i − 1][j − 1], dp[i − 1][j] + 1)
- If str[i] is not equal to X[j], str[i] can be kept as it is.
- Update dp[i][j] = dp[i – 1][j]
- If str[i] is equal to X[j],
- Print the minimum removals i.e, dp[N – 1][M – 1]
Below is the implementation of the above approach:
C++
// C++ implementation of// the above approach#include <bits/stdc++.h>using namespace std;// Function to print the minimum number of// character removals required to remove X// as a subsequence from the string strvoid 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 Codeint 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 approachimport 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 strdef 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 Codeif __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 approachusing 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 codepublic 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
<script>// Javascript program for the above approach// Function to print the minimum number of// character removals required to remove X// as a subsequence from the string strfunction printMinimumRemovals(str,X){ // Length of the string str let N = str.length; // Length of the string X let M = X.length; // Stores the dp states let dp = new Array(N); for(let i=0;i<N;i++) { dp[i]=new Array(M); for(let j=0;j<M;j++) { dp[i][j]=0; } } // Fill first row of dp[][] for (let j = 0; j < M; j++) { // If X[j] matches with str[0] if (str[0] == X[j]) { dp[0][j] = 1; } } for (let i = 1; i < N; i++) { for (let 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 document.write(dp[N - 1][M - 1]);} // Driver codelet str = "btagd";let X = "bad";// Function call to get minimum// number of character removalsprintMinimumRemovals(str, X);// This code is contributed by avanitrachhadiya2155</script> |
1
Time Complexity: O(N * M)
Auxiliary Space: O(N * M)
Efficient Approach : using array instead of 2d matrix to optimize space complexity
In previous code we can se that dp[i][j] is dependent upon dp[i+1][j-1] or dp[i][j-1] so we can assume that dp[i+1] is current row and dp[i] is previous row.
Implementations Steps :
- It initializes two vectors curr and prev of length N+1 with all elements as 0.
- Then it iterates over the length of the string str and X using nested loops.
- If str[i] is equal to X[j], it updates the current state after removing str[i] and also the current state after keeping str[i] and removing X[j].
- If str[i] is not equal to X[j], it updates the current state with the previous state value of the same index.
- Finally, it prints the last element of the curr vector as the minimum number of character removals.
Implementation :
C++
// C++ implementation of the above approach#include <bits/stdc++.h>using namespace std;// Function to print the minimum number of// character removals required to remove X// as a subsequence from the string strvoid 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 rows dp states in 2 vectors vector<int>curr(M+1 ,0); vector<int>prev(M+1 ,0); // Fill first row of dp[][] for (int j = 0; j < M; j++) { // If X[j] matches with str[0] if (str[0] == X[j]) { curr[j] = 1; prev[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[ curr[j] = prev[j] + 1; // Update state after keeping str[i] if (j != 0) curr[j] = min(curr[j], prev[j - 1]); } // If str[i] is not equal to X[j] else { curr[j] = prev[j]; } } prev = curr; } // Print the minimum number // of characters removals cout << curr[M - 1];}// Driver Codeint main(){ // Input string str = "btagd"; string X = "bad"; // Function call to get minimum // number of character removals printMinimumRemovals(str, X); return 0;}// this code is contributed by bhardwajji |
Java
import java.util.Arrays;public class Main { // Function to print the minimum number of // character removals required to remove X // as a subsequence from the string str public 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 rows dp states in 2 arrays int[] curr = new int[M+1]; int[] prev = new int[M+1]; // 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)) { curr[j] = 1; prev[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] curr[j] = prev[j] + 1; // Update state after keeping str[i] if (j != 0) curr[j] = Math.min(curr[j], prev[j - 1]); } // If str[i] is not equal to X[j] else { curr[j] = prev[j]; } } prev = Arrays.copyOf(curr, curr.length); // Update the previous row with current row } // Print the minimum number // of characters removals System.out.println(curr[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); }} |
Python3
def printMinimumRemovals(str, X): # Length of the string str N = len(str) # Length of the string X M = len(X) # Stores the rows dp states in 2 vectors curr = [0]*(M+1) prev = [0]*(M+1) # Fill first row of dp[][] for j in range(M): # If X[j] matches with str[0] if str[0] == X[j]: curr[j] = 1 prev[j] = 1 for i in range(1, N): for j in range(M): # If str[i] is equal to X[j] if str[i] == X[j]: # Update state after removing str[i[ curr[j] = prev[j] + 1 # Update state after keeping str[i] if j != 0: curr[j] = min(curr[j], prev[j - 1]) # If str[i] is not equal to X[j] else: curr[j] = prev[j] prev = curr.copy() # Print the minimum number # of characters removals print(curr[M - 1])# Driver Codestr = "btagd"X = "bad"# Function call to get minimum# number of character removalsprintMinimumRemovals(str, X) |
C#
using System;using System.Collections.Generic;class Program{ // 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 rows dp states in 2 lists List<int> curr = new List<int>(M + 1); List<int> prev = new List<int>(M + 1); for (int i = 0; i < M + 1; i++) { curr.Add(0); prev.Add(0); } // Fill first row of dp[][] for (int j = 0; j < M; j++) { // If X[j] matches with str[0] if (str[0] == X[j]) { curr[j] = 1; prev[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[ curr[j] = prev[j] + 1; // Update state after keeping str[i] if (j != 0) curr[j] = Math.Min(curr[j], prev[j - 1]); } // If str[i] is not equal to X[j] else { curr[j] = prev[j]; } } prev = new List<int>(curr); } // Print the minimum number // of characters removals Console.WriteLine(curr[M - 1]); } // Driver Code static void Main(string[] args) { // Input string str = "btagd"; string X = "bad"; // Function call to get minimum // number of character removals PrintMinimumRemovals(str, X); }} |
Javascript
// JavaScript implementation of the above approachfunction printMinimumRemovals(str, X) { // Length of the string strlet N = str.length;// Length of the string Xlet M = X.length;// Stores the rows dp states in 2 arrays let curr = Array(M + 1).fill(0);let prev = Array(M + 1).fill(0);// Fill first row of dp[][]for (let j = 0; j < M; j++) { // If X[j] matches with str[0] if (str[0] === X[j]) { curr[j] = 1; prev[j] = 1; }}for (let i = 1; i < N; i++) { for (let j = 0; j < M; j++) { // If str[i] is equal to X[j] if (str[i] === X[j]) { // Update state after removing str[i[ curr[j] = prev[j] + 1; // Update state after keeping str[i] if (j !== 0) curr[j] = Math.min(curr[j], prev[j - 1]); } // If str[i] is not equal to X[j] else { curr[j] = prev[j]; } } prev = [...curr];}// Print the minimum number// of characters removalsconsole.log(curr[M - 1]);}// Driver Codelet str = "btagd";let X = "bad";// Function call to get minimum// number of character removalsprintMinimumRemovals(str, X); |
Output:
1
Time Complexity : O(N*M), where N is the size of the first string and M is the size of the second string
Auxiliary Space: O(M), Space used for storing previous values
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



