Skip to content
geeksforgeeks
  • Tutorials
    • Python
    • Java
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
    • Practice Coding Problems
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • DSA
  • Interview Problems on DP
  • Practice DP
  • MCQs on DP
  • Tutorial on Dynamic Programming
  • Optimal Substructure
  • Overlapping Subproblem
  • Memoization
  • Tabulation
  • Tabulation vs Memoization
  • 0/1 Knapsack
  • Unbounded Knapsack
  • Subset Sum
  • LCS
  • LIS
  • Coin Change
  • Word Break
  • Egg Dropping Puzzle
  • Matrix Chain Multiplication
  • Palindrome Partitioning
  • DP on Arrays
  • DP with Bitmasking
  • Digit DP
  • DP on Trees
  • DP on Graph
Open In App
Next Article:
Minimum number of deletions and insertions to transform one string into another
Next article icon

Minimum number of deletions and insertions to transform one string into another

Last Updated : 16 Nov, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report
Try it on GfG Practice
redirect icon

Given two strings s1 and s2. The task is to remove/delete and insert the minimum number of characters from s1 to transform it into s2. It could be possible that the same character needs to be removed/deleted from one point of s1 and inserted at another point.

Example 1: 

Input: s1 = "heap", s2 = "pea"
Output: 3
Explanation: Minimum Deletion = 2 and Minimum Insertion = 1
p and h are deleted from the heap, and then p is inserted at the beginning. One thing to note, though p was required it was removed/deleted first from its position and then it was inserted into some other position. Thus, p contributes one to the deletion count and one to the insertion count.

Input: s1 = "geeksforgeeks", s2 = "geeks"
Output: 8
Explanation: 8 deletions, i.e. remove all characters of the string "forgeeks".

Table of Content

  • Using Recursion - O(2^n) Time and O(n) Space
  • Using Top-Down DP (Memoization) - O(n^2) Time and O(n^2) Space
  • Using Bottom-Up DP (Tabulation) - O(n^2) Time and O(n^2) Space
  • Using Bottom-Up DP (Space-Optimization)– O(n^2) Time and O(n) Space

Using Recursion - O(2^n) Time and O(n) Space

A simple approach to solve the problem involves generating all subsequences of s1 and, for each subsequence, calculating the minimum deletions and insertions required to transform it into s2. An efficent approach uses the concept of longest common subsequence (LCS) to find length of longest LCS. Once we have LCS of two strings, we can find Minimum Insertion and Deletions to convert s1 into s2.

  • To minimize deletions, we only need to remove characters from s1 that are not part of the longest common subsequence (LCS) with s2. This can be determined by subtracting the LCS length from the length of s1. Thus, the minimum number of deletions is:
    minDeletions = length of s1 - LCS length.
  • Similarly, to minimize insertions, we only need to insert characters from s2 into s1 that are not part of the LCS. This can be determined by subtracting the LCS length from the length of s2. Thus, the minimum number of insertions is:
    minInsertions = length of s2 - LCS length.
C++
// C++ program to find the minimum number of insertion and deletion // using recursion.  #include <iostream> using namespace std;  int lcs(string &s1, string &s2, int m, int n) {        // Base case: If either string is empty,     // the LCS length is 0     if (m == 0 || n == 0)         return 0;      // If the last characters of both substrings match     if (s1[m - 1] == s2[n - 1])         // Include the matching character in LCS and         // recurse for remaining substrings         return 1 + lcs(s1, s2, m - 1, n - 1);      else         // If the last characters do not match,        // find the maximum LCS length by:         // 1. Excluding the last character of s1         // 2. Excluding the last character of s2         return max(lcs(s1, s2, m, n - 1), lcs(s1, s2, m - 1, n)); }  int minOperations(string s1, string s2) {     int m = s1.size();     int n = s2.size();      // the length of the LCS for s1[0..m-1]   // and s2[0..n-1]     int len = lcs(s1, s2, m, n);      // Characters to delete from s1     int minDeletions = m - len;      // Characters to insert into s1     int minInsertions = n - len;      // Total operations needed     int total = minDeletions + minInsertions;     return total; }  int main() {     string s1 = "AGGTAB";     string s2 = "GXTXAYB";     int res = minOperations(s1, s2);     cout << res;     return 0; } 
Java
// Java program to find the minimum number of insertions and // deletions using recursion.  class GfG {        static int lcs(String s1, String s2, int m, int n) {                // Base case: If either string is empty, the LCS         // length is 0         if (m == 0 || n == 0) {             return 0;         }          // If the last characters of both substrings match         if (s1.charAt(m - 1) == s2.charAt(n - 1)) {              // Include the matching character in LCS             // and recurse for remaining substrings             return 1 + lcs(s1, s2, m - 1, n - 1);         }         else {                        // If the last characters do not match,             // find the maximum LCS length by:             // 1. Excluding the last character of s1             // 2. Excluding the last character of s2             return Math.max(lcs(s1, s2, m, n - 1),                             lcs(s1, s2, m - 1, n));         }     }      static int minOperations(String s1, String s2) {         int m = s1.length();         int n = s2.length();          // the length of LCS for s1[0..m-1] and         //  s2[0..n-1]         int len = lcs(s1, s2, m, n);          // Characters to delete from s1         int minDeletions = m - len;          // Characters to insert into s2         int minInsertions = n - len;          // Total operations needed         return minDeletions + minInsertions;     }      public static void main(String[] args) {         String s1 = "AGGTAB";         String s2 = "GXTXAYB";          int res = minOperations(s1, s2);         System.out.println(res);     } } 
Python
# Python program to find the minimum number of insertions # and deletions using recursion   def lcs(s1, s2, m, n):      # Base case: If either string is empty,     # the LCS length is 0     if m == 0 or n == 0:         return 0      # If the last characters of both substrings match     if s1[m - 1] == s2[n - 1]:          # Include the matching character in LCS and          # recurse for remaining substrings         return 1 + lcs(s1, s2, m - 1, n - 1)     else:                # If the last characters do not match,          # find the maximum LCS length by:         # 1. Excluding the last character of s1         # 2. Excluding the last character of s2         return max(lcs(s1, s2, m, n - 1), lcs(s1, s2, m - 1, n))   def minOperations(s1, s2):      m = len(s1)     n = len(s2)      # the length of LCS for s1[0..m-1] and s2[0..n-1]     lengthLcs = lcs(s1, s2, m, n)      # Characters to delete from str1     minDeletions = m - lengthLcs      # Characters to insert into str1     minInsertions = n - lengthLcs      # Total operations needed     return minDeletions + minInsertions   if __name__ == "__main__":     s1 = "AGGTAB"     s2 = "GXTXAYB"      result = minOperations(s1, s2)     print(result) 
C#
// C# program to find the minimum number of insertions and // deletions using recursion.  using System; class GfG {     static int lcs(string s1, string s2, int m, int n) {                // Base case: If either string is empty, the LCS         // length is 0         if (m == 0 || n == 0)             return 0;          // If the last characters of both substrings match         if (s1[m - 1] == s2[n - 1]) {                        // Include the matching character in LCS             // and recurse for remaining substrings             return 1 + lcs(s1, s2, m - 1, n - 1);         }         else {                        // If the last characters do not match,             // find the maximum LCS length by:             // 1. Excluding the last character of s1             // 2. Excluding the last character of s2             return Math.Max(lcs(s1, s2, m, n - 1),                             lcs(s1, s2, m - 1, n));         }     }      static int minOperations(string s1, string s2) {         int m = s1.Length;         int n = s2.Length;          // the length of LCS for s1[0..m-1] and         // s2[0..n-1]         int lengthLcs = lcs(s1, s2, m, n);          // Characters to delete from s1         int minDeletions = m - lengthLcs;          // Characters to insert into s2         int minInsertions = n - lengthLcs;          // Total operations needed         return minDeletions + minInsertions;     }      static void Main(string[] args) {         string s1 = "AGGTAB";         string s2 = "GXTXAYB";          int result = minOperations(s1, s2);         Console.WriteLine(result);     } } 
JavaScript
// JavaScript program to find the minimum number of // insertions and deletions using recursion  function lcs(s1, s2, m, n) {      // Base case: If either string is empty, the LCS length     // is 0     if (m === 0 || n === 0) {         return 0;     }      // If the last characters of both substrings match     if (s1[m - 1] === s2[n - 1]) {               // Include the matching character in LCS and recurse         // for remaining substrings         return 1 + lcs(s1, s2, m - 1, n - 1);     }     else {              // If the last characters do not match, find the         // maximum LCS length by:         // 1. Excluding the last character of s1         // 2. Excluding the last character of s2         return Math.max(lcs(s1, s2, m, n - 1),                         lcs(s1, s2, m - 1, n));     } }  function minOperations(s1, s2) {     const m = s1.length;     const n = s2.length;      // Length of the LCS     const len = lcs(s1, s2, m, n);      // Characters to delete from s1     const minDeletions = m - len;      // Characters to insert into s1     const minInsertions = n - len;      // Total operations needed     return minDeletions + minInsertions; }  const s1 = "AGGTAB"; const s2 = "GXTXAYB";  const res = minOperations(s1, s2); console.log(res); 

Output
5

Using Top-Down DP (Memoization) - O(n^2) Time and O(n^2) Space

In this approach, we apply memoization to store the results of overlapping subproblems while finding the Longest Common Subsequence (LCS). A 2D array memo is used to save the LCS lengths for different substrings of the two input strings, ensuring that each subproblem is solved only once.
This method is similar to Longest Common Subsequence (LCS) problem using memoization.

C++
// C++ program to find the minimum of insertion and deletion // using memoization.  #include <iostream> #include <vector> using namespace std;  int lcs(string &s1, string &s2, int m, int n,          vector<vector<int>> &memo) {        // Base case: If either string is empty, the LCS length is 0     if (m == 0 || n == 0)         return 0;       // If the value is already computed, return     // it from the memo array      if(memo[m][n]!=-1)         return memo[m][n];         // If the last characters of both substrings match     if (s1[m - 1] == s2[n - 1])                // Include the matching character in LCS and recurse for        // remaining substrings         return memo[m][n] = 1 + lcs(s1, s2, m - 1, n - 1, memo);      else                // If the last characters do not match, find the maximum LCS length by:         // 1. Excluding the last character of s1         // 2. Excluding the last character of s2         return memo[m][n] = max(lcs(s1, s2, m, n - 1, memo),                                 lcs(s1, s2, m - 1, n, memo)); }  int minOperations(string s1, string s2) {        int m = s1.size();       int n = s2.size();              // Initialize the memoization array with -1.   vector<vector<int>> memo = vector<vector<int>>     						(m+1,vector<int>(n+1,-1));         // the length of the LCS for    	// s1[0..m-1] and s2[0..n-1]     int len = lcs(s1, s2, m, n, memo);      // Characters to delete from s1     int minDeletions = m - len;      // Characters to insert into s1     int minInsertions = n - len;      // Total operations needed     int total = minDeletions + minInsertions;     return total; }  int main() {        string s1 = "AGGTAB";     string s2 = "GXTXAYB";     int res = minOperations(s1, s2);     cout << res;     return 0; } 
Java
// Java program to find the minimum of insertion and deletion // using memoization.  class GfG {      static int lcs(String s1, String s2, int m, int n, int[][] memo) {                // Base case: If either string is empty,        	// the LCS length is 0         if (m == 0 || n == 0) {                 return 0;         }          // If the value is already computed, return it       	// from the memo array         if (memo[m][n] != -1) {             return memo[m][n];         }          // If the last characters of both substrings match         if (s1.charAt(m - 1) == s2.charAt(n - 1)) {              // Include the matching character in LCS and recurse for            // remaining substrings             memo[m][n] = 1 + lcs(s1, s2, m - 1, n - 1, memo);         }         else {                        // If the last characters do not match,             // find the maximum LCS length by:             // 1. Excluding the last character of s1             // 2. Excluding the last character of s2             memo[m][n] = Math.max(lcs(s1, s2, m, n - 1, memo),                                   lcs(s1, s2, m - 1, n, memo));         }         return memo[m][n];     }      static int minOperations(String s1, String s2) {                int m = s1.length();            int n = s2.length();             // Initialize the memoization array with -1        	// (indicating uncalculated values)         int[][] memo = new int[m + 1][n + 1];         for (int i = 0; i <= m; i++) {             for (int j = 0; j <= n; j++) {                 memo[i][j] = -1;             }         }          // the length of LCS for s1[0..m-1] and s2[0..n-1]         int len = lcs(s1, s2, m, n, memo);          // Characters to delete from s1         int minDeletions = m - len;          // Characters to insert into s1         int minInsertions = n - len;          // Total operations needed         return minDeletions + minInsertions;     }     static void main(String[] args) {                String s1 = "AGGTAB";            String s2 = "GXTXAYB";           int res = minOperations(s1, s2);           System.out.println(res);        } } 
Python
# Python program to find the minimum number of insertions and  # deletions using memoization  def lcs(s1, s2, m, n, memo):        # Base case: If either string is empty, the LCS length is 0     if m == 0 or n == 0:         return 0      # If the value is already computed,      # return it from the memo array     if memo[m][n] != -1:         return memo[m][n]      # If the last characters of both substrings match     if s1[m - 1] == s2[n - 1]:                # Include the matching character in LCS and          # recurse for remaining substrings         memo[m][n] = 1 + lcs(s1, s2, m - 1, n - 1, memo)     else:                # If the last characters do not match,          # find the maximum LCS length by:         # 1. Excluding the last character of s1         # 2. Excluding the last character of s2         memo[m][n] = max(lcs(s1, s2, m, n - 1, memo),                          lcs(s1, s2, m - 1, n, memo))          # Return the computed value     return memo[m][n]   def minOperations(s1, s2):     m = len(s1)        n = len(s2)         # Initialize the memoization array with -1     # (indicating uncalculated values)     memo = [[-1 for _ in range(n + 1)] for _ in range(m + 1)]      # Calculate the length of LCS for s1[0..m-1] and s2[0..n-1]     lengthLcs = lcs(s1, s2, m, n, memo)      # Characters to delete from s1     minDeletions = m - lengthLcs      # Characters to insert into s1     minInsertions = n - lengthLcs      # Total operations needed     return minDeletions + minInsertions   if __name__ == "__main__":     s1 = "AGGTAB"     s2 = "GXTXAYB"      res = minOperations(s1, s2)     print(res)   
C#
// C# program to find the minimum of insertion and deletion // using memoization.  using System;  class GfG {          static int lcs(string s1, string s2, int m, int n,                        int[, ] memo) {                // Base case: If either string is empty, the LCS         // length is 0         if (m == 0 || n == 0) {             return 0;         }          // If the value is already computed, return it from         // the memo array         if (memo[m, n] != -1) {             return memo[m, n];         }          // If the last characters of both substrings match         if (s1[m - 1] == s2[n - 1]) {                        // Include the matching character in LCS and             // recurse for remaining substrings             memo[m, n]                 = 1 + lcs(s1, s2, m - 1, n - 1, memo);         }         else {                        // If the last characters do not match, find the             // maximum LCS length by:             // 1. Excluding the last character of s1             // 2. Excluding the last character of s2             memo[m, n]                 = Math.Max(lcs(s1, s2, m, n - 1, memo),                            lcs(s1, s2, m - 1, n, memo));         }          // Return the computed value         return memo[m, n];     }       static int minOperations(string s1, string s2) {                int m = s1.Length;           int n = s2.Length;            // Initialize the memoization array with -1         // (indicating uncalculated values)         int[, ] memo = new int[m + 1, n + 1];         for (int i = 0; i <= m; i++) {             for (int j = 0; j <= n; j++) {                 memo[i, j] = -1;             }         }          // Calculate the length of LCS for s1[0..m-1] and         // s2[0..n-1]         int lengthLcs = lcs(s1, s2, m, n, memo);          // Characters to delete from s1         int minDeletions = m - lengthLcs;          // Characters to insert into s1         int minInsertions = n - lengthLcs;          // Total operations needed         return minDeletions + minInsertions;     }          static void Main(string[] args) {                string s1 = "AGGTAB";         string s2 = "GXTXAYB";         int res = minOperations(s1, s2);         Console.WriteLine(res);       } } 
JavaScript
// JavaScript program to find the minimum number of // insertions and deletions using memoization  function lcs(s1, s2, m, n, memo) {      // Base case: If either string is empty, the LCS length     // is 0     if (m === 0 || n === 0) {         return 0;     }      // If the value is already computed, return it from the     // memo array     if (memo[m][n] !== -1) {         return memo[m][n];     }      // If the last characters of both substrings match     if (s1[m - 1] === s2[n - 1]) {              // Include the matching character in LCS and recurse         // for remaining substrings         memo[m][n] = 1 + lcs(s1, s2, m - 1, n - 1, memo);     }     else {              // If the last characters do not match, find the         // maximum LCS length by:         // 1. Excluding the last character of s1         // 2. Excluding the last character of s2         memo[m][n] = Math.max(lcs(s1, s2, m, n - 1, memo),                               lcs(s1, s2, m - 1, n, memo));     }        return memo[m][n]; }  function minOperations(s1, s2){      const m = s1.length;     const n = s2.length;      // Initialize the memoization array with -1 (indicating     // uncalculated values)     const memo = Array.from({length : m + 1},                             () => Array(n + 1).fill(-1));      // Calculate the length of LCS for s1[0..m-1] and     // s2[0..n-1]     const len = lcs(s1, s2, m, n, memo);      // Characters to delete from s1     const minDeletions = m - len;      // Characters to insert into s1     const minInsertions = n - len;      // Total operations needed     return minDeletions + minInsertions; }  const s1 = "AGGTAB"; const s2 = "GXTXAYB";  const res = minOperations(s1, s2); console.log(res); 

Output
5

Using Bottom-Up DP (Tabulation) - O(n^2) Time and O(n^2) Space

The approach is similar to the previous one, just instead of breaking down the problem recursively, we iteratively build up the solution by calculating in bottom-up manner. We maintain a 2D dp[][] table, such that dp[i][j], stores the Longest Common Subsequence (LCS) for the subproblem(i, j).
This approach is similar to finding LCS in bottom-up manner.

C++
// C++ program to find the minimum of insertion and deletion // using tabulation.  #include <iostream> #include <vector> using namespace std;   int lcs(string &s1, string &s2) {        int m = s1.size();     int n = s2.size();      // Initializing a matrix of size (m+1)*(n+1)     vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));      // Building dp[m+1][n+1] in bottom-up fashion     for (int i = 1; i <= m; ++i) {         for (int j = 1; j <= n; ++j) {             if (s1[i - 1] == s2[j - 1])                 dp[i][j] = dp[i - 1][j - 1] + 1;             else                 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);         }     }      // dp[m][n] contains length of LCS for s1[0..m-1]     // and s2[0..n-1]     return dp[m][n]; }  int minOperations(string s1, string s2) {        int m = s1.size();     int n = s2.size();      // the length of the LCS for   	// s1[0..m-1] and s2[0..n-1]     int len = lcs(s1, s2);      // Characters to delete from s1     int minDeletions = m - len;      // Characters to insert into s1     int minInsertions = n - len;      // Total operations needed     int total = minDeletions + minInsertions;     return total; } int main() {        string s1 = "AGGTAB";     string s2 = "GXTXAYB";     int res = minOperations(s1, s2);     cout << res;      return 0; } 
Java
// Java program to find the minimum of insertion and // deletion using tabulation.  class GfG {       static int lcs(String s1, String s2) {                int m = s1.length();         int n = s2.length();          // Initializing a matrix of size (m+1)*(n+1)         int[][] dp = new int[m + 1][n + 1];          // Building dp[m+1][n+1] in bottom-up fashion         for (int i = 1; i <= m; ++i) {             for (int j = 1; j <= n; ++j) {                 if (s1.charAt(i - 1) == s2.charAt(j - 1))                     dp[i][j] = dp[i - 1][j - 1] + 1;                 else                     dp[i][j] = Math.max(dp[i - 1][j],                                         dp[i][j - 1]);             }         }          // dp[m][n] contains length of LCS for s1[0..m-1]         // and s2[0..n-1]         return dp[m][n];     }      static int minOperations(String s1, String s2) {                int m = s1.length();         int n = s2.length();          // the length of the LCS for s1[0..m-1] and         // str2[0..n-1]         int len = lcs(s1, s2);          // Characters to delete from s1         int minDeletions = m - len;          // Characters to insert into s1         int minInsertions = n - len;          // Total operations needed         return minDeletions + minInsertions;     }      public static void main(String[] args) {                String s1 = "AGGTAB";         String s2 = "GXTXAYB";         int res = minOperations(s1, s2);         System.out.println(res);     } } 
Python
# Python program to find the minimum of insertion and deletion # using tabulation.    def lcs(s1, s2):     m = len(s1)     n = len(s2)      # Initializing a matrix of size (m+1)*(n+1)     dp = [[0] * (n + 1) for _ in range(m + 1)]      # Building dp[m+1][n+1] in bottom-up fashion     for i in range(1, m + 1):         for j in range(1, n + 1):             if s1[i - 1] == s2[j - 1]:                 dp[i][j] = dp[i - 1][j - 1] + 1             else:                 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])      # dp[m][n] contains length of LCS for     # s1[0..m-1] and s2[0..n-1]     return dp[m][n]   def minOperations(s1, s2):     m = len(s1)     n = len(s2)      # the length of the LCS for      # s1[0..m-1] and s2[0..n-1]     lengthLcs = lcs(s1, s2)      # Characters to delete from s1     minDeletions = m - lengthLcs      # Characters to insert into s1     minInsertions = n - lengthLcs      # Total operations needed     return minDeletions + minInsertions   s1 = "AGGTAB" s2 = "GXTXAYB" res = minOperations(s1, s2) print(res) 
C#
// C# program to find the minimum of insertion and deletion // using tabulation.  using System;  class GfG {          static int Lcs(string s1, string s2) {                int m = s1.Length;         int n = s2.Length;          // Initializing a matrix of size (m+1)*(n+1)         int[, ] dp = new int[m + 1, n + 1];          // Building dp[m+1][n+1] in bottom-up fashion         for (int i = 1; i <= m; ++i) {             for (int j = 1; j <= n; ++j) {                 if (s1[i - 1] == s2[j - 1])                     dp[i, j] = dp[i - 1, j - 1] + 1;                 else                     dp[i, j] = Math.Max(dp[i - 1, j],                                         dp[i, j - 1]);             }         }          // dp[m, n] contains length of LCS for s1[0..m-1]         // and s2[0..n-1]         return dp[m, n];     }      static int minOperations(string s1, string s2) {                int m = s1.Length;         int n = s2.Length;          // the length of the LCS for s1[0..m-1] and         // s2[0..n-1]         int len = Lcs(s1, s2);          // Characters to delete from str1         int minDeletions = m - len;          // Characters to insert into str1         int minInsertions = n - len;          // Total operations needed         return minDeletions + minInsertions;     }      static void Main() {                string s1 = "AGGTAB";         string s2 = "GXTXAYB";         int res = minOperations(s1, s2);         Console.WriteLine(res);     } } 
JavaScript
// JavaScript program to find the minimum of insertion and // deletion using tabulation.  function lcs(s1, s2) {      let m = s1.length;     let n = s2.length;      // Initializing a matrix of size (m+1)*(n+1)     let dp = Array(m + 1).fill().map(         () => Array(n + 1).fill(0));      // Building dp[m+1][n+1] in bottom-up fashion     for (let i = 1; i <= m; ++i) {         for (let j = 1; j <= n; ++j) {             if (s1[i - 1] === s2[j - 1])                 dp[i][j] = dp[i - 1][j - 1] + 1;             else                 dp[i][j]                     = Math.max(dp[i - 1][j], dp[i][j - 1]);         }     }      // dp[m][n] contains length of LCS for s1[0..m-1] and     // s2[0..n-1]     return dp[m][n]; }  function minOperations(s1, s2) {      let m = s1.length;     let n = s2.length;      // the length of the LCS for s1[0..m-1] and s2[0..n-1]     let len = lcs(s1, s2);      // Characters to delete from s1     let minDeletions = m - len;      // Characters to insert into s1     let minInsertions = n - len;      // Total operations needed     return minDeletions + minInsertions; }  let s1 = "AGGTAB"; let s2 = "GXTXAYB"; let res = minOperations(s1, s2); console.log(res); 

Output
5

Using Bottom-Up DP (Space-Optimization)– O(n^2) Time and O(n) Space

In the previous approach, the longest common subsequence (LCS) algorithm uses O(n * n) space to store the entire dp table. However, since each value in dp[i][j] only depends on the current row and the previous row, we don’t need to store the entire table. This can be optimized by storing only the current and previous rows. For more details, refer to A Space Optimized Solution of LCS.

C++
// C++ program to find the minimum of insertion and deletion // using space optimized.  #include <bits/stdc++.h> using namespace std;  int lcs(string &s1, string &s2) {        int m = s1.length(), n = s2.length();      vector<vector<int>> dp(2, vector<int>(n + 1));      for (int i = 0; i <= m; i++) {          // Compute current binary index. If i is even         // then curr = 0, else 1         bool curr = i & 1;          for (int j = 0; j <= n; j++) {                        // Initialize first row and first column with 0             if (i == 0 || j == 0)                 dp[curr][j] = 0;              else if (s1[i - 1] == s2[j - 1])                 dp[curr][j] = dp[1 - curr][j - 1] + 1;              else                 dp[curr][j] = max(dp[1 - curr][j], dp[curr][j - 1]);         }     }      return dp[m & 1][n]; }  int minOperations(string s1, string s2) {     int m = s1.size();     int n = s2.size();      // the length of the LCS for s1[0..m-1] and s2[0..n-1]     int len = lcs(s1, s2);      // Characters to delete from s1     int minDeletions = m - len;      // Characters to insert into s1     int minInsertions = n - len;      // Total operations needed     int total = minDeletions + minInsertions;     return total; }  int main() {     string s1 = "AGGTAB";     string s2 = "GXTXAYB";     int res = minOperations(s1, s2);     cout << res;     return 0; } 
Java
// Java program to find the minimum of insertion and // deletion using space optimized.  class GfG {       static int lcs(String s1, String s2) {                int m = s1.length();         int n = s2.length();          // Initializing a 2D array with size (2) x (n + 1)         int[][] dp = new int[2][n + 1];          for (int i = 0; i <= m; i++) {              // Compute current binary index. If i is even,             // then curr = 0, else 1             int curr = i % 2;              for (int j = 0; j <= n; j++) {                                // Initialize first row and first column                 // with 0                 if (i == 0 || j == 0)                     dp[curr][j] = 0;                 else if (s1.charAt(i - 1)                          == s2.charAt(j - 1))                     dp[curr][j] = dp[1 - curr][j - 1] + 1;                 else                     dp[curr][j] = Math.max(dp[1 - curr][j],                                            dp[curr][j - 1]);             }         }          return dp[m % 2][n];     }      static int minOperations(String s1, String s2) {                int m = s1.length();         int n = s2.length();          // the length of the LCS for s1[0..m-1] and         // s2[0..n-1]         int len = lcs(s1, s2);          // Characters to delete from s1         int minDeletions = m - len;          // Characters to insert into s1         int minInsertions = n - len;          // Total operations needed         return minDeletions + minInsertions;     }      public static void main(String[] args) {                String s1 = "AGGTAB";         String s2 = "GXTXAYB";         int res = minOperations(s1, s2);         System.out.println(res);     } } 
Python
# Python program to find the minimum of insertion and deletion # using space optimized.   def lcs(s1, s2):     m = len(s1)     n = len(s2)      # Initializing a matrix of size (2)*(n+1)     dp = [[0] * (n + 1) for _ in range(2)]      for i in range(m + 1):          # Compute current binary index. If i is even         # then curr = 0, else 1         curr = i % 2          for j in range(n + 1):              # Initialize first row and first column with 0             if i == 0 or j == 0:                 dp[curr][j] = 0              # If the last characters of both substrings match             elif s1[i - 1] == s2[j - 1]:                 dp[curr][j] = dp[1 - curr][j - 1] + 1              # If the last characters do not match,             # find the maximum LCS length by:             # 1. Excluding the last character of s1             # 2. Excluding the last character of s2             else:                 dp[curr][j] = max(dp[1 - curr][j], dp[curr][j - 1])      # dp[m & 1][n] contains length of LCS for s1[0..m-1] and s2[0..n-1]     return dp[m % 2][n]   def minOperations(s1, s2):     m = len(s1)     n = len(s2)      # the length of the LCS for s1[0..m-1] and s2[0..n-1]     length = lcs(s1, s2)      # Characters to delete from s1     minDeletions = m - length      # Characters to insert into s1     minInsertions = n - length      # Total operations needed     return minDeletions + minInsertions   s1 = "AGGTAB" s2 = "GXTXAYB" res = minOperations(s1, s2) print(res) 
C#
// C# program to find the minimum of insertion and deletion // using space optimized.  using System;  class GfG {     static int lcs(string s1, string s2) {                int m = s1.Length;         int n = s2.Length;          // Initializing a matrix of size (2)*(n+1)         int[][] dp = new int[2][];         dp[0] = new int[n + 1];         dp[1] = new int[n + 1];          for (int i = 0; i <= m; i++) {                        // Compute current binary index. If i is even             // then curr = 0, else 1             int curr = i % 2;              for (int j = 0; j <= n; j++) {                                // Initialize first row and first column                 // with 0                 if (i == 0 || j == 0)                     dp[curr][j] = 0;                  // If the last characters of both substrings                 // match                 else if (s1[i - 1] == s2[j - 1])                     dp[curr][j] = dp[1 - curr][j - 1] + 1;                  // If the last characters do not match,                 // find the maximum LCS length by:                 // 1. Excluding the last character of s1                 // 2. Excluding the last character of s2                 else                     dp[curr][j] = Math.Max(dp[1 - curr][j],                                            dp[curr][j - 1]);             }         }          // dp[m & 1][n] contains length of LCS for         // s1[0..m-1] and s2[0..n-1]         return dp[m % 2][n];     }      static int minOperations(string s1, string s2) {                int m = s1.Length;         int n = s2.Length;          // the length of the LCS for s1[0..m-1] and         // s2[0..n-1]         int length = lcs(s1, s2);          // Characters to delete from s1         int minDeletions = m - length;          // Characters to insert into s1         int minInsertions = n - length;          // Total operations needed         return minDeletions + minInsertions;     }      static void Main(string[] args) {                string s1 = "AGGTAB";         string s2 = "GXTXAYB";         int res = minOperations(s1, s2);         Console.WriteLine(res);     } } 
JavaScript
// JavaScript program to find the minimum of insertion and // deletion using space optimized.  function lcs(s1, s2) {      const m = s1.length;     const n = s2.length;      // Initializing a matrix of size (2)*(n+1)     const dp         = Array(2).fill().map(() => Array(n + 1).fill(0));      for (let i = 0; i <= m; i++) {              // Compute current binary index. If i is even         // then curr = 0, else 1         const curr = i % 2;          for (let j = 0; j <= n; j++) {                      // Initialize first row and first column with 0             if (i === 0 || j === 0)                 dp[curr][j] = 0;              // If the last characters of both substrings             // match             else if (s1[i - 1] === s2[j - 1])                 dp[curr][j] = dp[1 - curr][j - 1] + 1;              // If the last characters do not match,             // find the maximum LCS length by:             // 1. Excluding the last character of s1             // 2. Excluding the last character of s2             else                 dp[curr][j] = Math.max(dp[1 - curr][j],                                        dp[curr][j - 1]);         }     }      // dp[m & 1][n] contains length of LCS for s1[0..m-1]     // and s2[0..n-1]     return dp[m % 2][n]; }  function minOperations(s1, s2) {      const m = s1.length;     const n = s2.length;      // the length of the LCS for s1[0..m-1] and s2[0..n-1]     const length = lcs(s1, s2);      // Characters to delete from s1     const minDeletions = m - length;      // Characters to insert into s1     const minInsertions = n - length;      // Total operations needed     return minDeletions + minInsertions; }  const s1 = "AGGTAB"; const s2 = "GXTXAYB"; const res = minOperations(s1, s2); console.log(res); 

Output
5

Next Article
Minimum number of deletions and insertions to transform one string into another

A

Ayush Jauhari
Improve
Article Tags :
  • Dynamic Programming
  • DSA
  • LCS
Practice Tags :
  • Dynamic Programming
  • LCS

Similar Reads

    Transform One String to Another using Minimum Number of Given Operation
    Given two strings A and B, the task is to convert A to B if possible. The only operation allowed is to put any character from A and insert it at front. Find if it's possible to convert the string. If yes, then output minimum no. of operations required for transformation.Examples: Input: A = "ABD", B
    15+ min read
    Minimum number of given operations required to convert a string to another string
    Given two strings S and T of equal length. Both strings contain only the characters '0' and '1'. The task is to find the minimum number of operations to convert string S to T. There are 2 types of operations allowed on string S: Swap any two characters of the string.Replace a '0' with a '1' or vice
    14 min read
    Minimum number of deletions to make a string palindrome | Set 2
    Given a string A, compute the minimum number of characters you need to delete to make resulting string a palindrome. Examples: Input : baca Output : 1 Input : geek Output : 2 We have discussed one approach in below post. Minimum number of deletions to make a string palindrome Below approach will use
    9 min read
    Transform string A into B by deleting characters from ends and reinserting at any position
    Given two strings A and B that are anagrams of each other, the task is to convert A to B if possible in minimum number of operations. An operation is defined as removing either the first or the last character in A and inserting it back anywhere in the string. Examples: Input: A = "edacb", B = "abcde
    13 min read
    Minimum cost to convert a string to another by replacing blanks
    Given two strings s1 and s2 with lower-case alphabets having length N. The strings s1 and s2 initially may contain some blanks, the task is to find minimum operations to convert a string s1 to s2. Initially, if there are any blanks they should be replaced by any same character which cost 0 andAny vo
    9 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences