Sunday, November 17, 2024
Google search engine
HomeData Modelling & AIMinimize removals to remove another string as a subsequence of a given...

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]
  • 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 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




<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 str
function 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 code
let str = "btagd";
let X = "bad";
// Function call to get minimum
// number of character removals
printMinimumRemovals(str, X);
 
 
// This code is contributed by avanitrachhadiya2155
</script>


Output: 

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 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 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 Code
int 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 Code
str = "btagd"
X = "bad"
 
# Function call to get minimum
# number of character removals
printMinimumRemovals(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 approach
 
function printMinimumRemovals(str, X) {
    // Length of the string str
let N = str.length;
 
// Length of the string X
let 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 removals
console.log(curr[M - 1]);
}
 
// Driver Code
let str = "btagd";
let X = "bad";
 
// Function call to get minimum
// number of character removals
printMinimumRemovals(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

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments