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: p and h are deleted from the heap, and then p is inserted at the beginning.Input: s1 = "geeksforgeeks", s2 = "geeks"
Output: 8
Explanation: 8 deletions, i.e. remove all extra characters from s1.
Table of Content
Using Recursion - O(2^n) Time and O(n) Space
This problem is mainly based on longest common subsequence (LCS) to find length of longest LCS.
- 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++ 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 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 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# 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 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.
// 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 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 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# 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 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).
// 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 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 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# 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 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++ 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 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 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# 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 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