The edit distance between two strings S1 and S2 is the minimum number of operations required to transform one string into the other.
The allowed operations are:
Add one character to the string.
Remove one character from the string.
Replace one character in the string.
Your task is to calculate the edit distance between two strings.
Examples:
Input: S1 = "LOVE", S2 = "MOVIE" Output: 2 Explanation: The two operations required to convert "LOVE" to "MOVIE" are:
Replace S1[0] with "M", so S1 becomes "MOVE".
Add "I" before index 3, so S1 becomes "MOVIE".
Input: S1 = "L", S2 = "LOLOLOL" Output: 6 Explanation: The 6 operations required to convert "L" to "LOLOLOL" are:
Add "O" at the last of S1, so S1 becomes "LO".
Add "L" at the last of S1, so S1 becomes "LOL".
Add "O" at the last of S1, so S1 becomes "LOLO".
Add "L" at the last of S1, so S1 becomes "LOLOL".
Add "O" at the last of S1, so S1 becomes "LOLOLO".
Add "L" at the last of S1, so S1 becomes "LOLOLOL".
Approach: To solve the problem, follow the below idea:
The idea is to process all characters one by one starting from either from left or right sides of both strings. Let us process from the right end of the strings, there are two possibilities for every pair of characters being traversed, either they match or they don’t match. If last characters of both string matches then there is no need to perform any operation So, recursively calculate the answer for rest of part of the strings. When last characters do not match, we can perform all three operations to match the last characters in the given strings, i.e. insert, replace, and remove. We then recursively calculate the result for the remaining part of the string. Upon completion of these operations, we will select the minimum answer.
Below is the recursive tree for this problem:
Recursion Tree for Edit Distance
When the last characters of strings matches. Make a recursive call EditDistance(M-1,N-1) to calculate the answer for remaining part of the strings.
When the last characters of strings don’t matches. Make three recursive calls as show below:
Insert str1[N-1] at last of str2: EditDistance(M, N-1)
Replace str2[M-1] with str1[N-1] : EditDistance(M-1, N-1)
Remove str2[M-1] : EditDistance(M-1, N)
Since, the above relation follows optimal substructure and overlapping subproblems, we can use tabulation to compute the result efficiently.
Below are the steps to convert the recursive approach to Bottom up approach:
Construct a 2D table dp[m + 1][n + 1] to store the solution of the sub-problems.
Before building the solution, we need to initialize the table with the smaller version of the solution i.e. base case. Here m = 0 and n=0 is the situation of the base case, so we initialize first column dp[i][0] with i and first row dp[0][j] with j.
We can easily define the iterative structure by using the recursive structure of the above recursive solution.
After filling the table iteratively, our final solution gets stored at the bottom right corner of the 2-D table i.e. we return dp[m][n] as an output.
Below is the implementation of the algorithm:
C++
// A Dynamic Programming based C++ program to find minimum// number operations to convert str1 to str2#include<bits/stdc++.h>usingnamespacestd;// Utility function to find the minimum of three numbersintmin(intx,inty,intz){returnmin(min(x,y),z);}inteditDistDP(stringstr1,stringstr2,intm,intn){// Create a table to store results of subproblemsintdp[m+1][n+1];// Fill d[][] in bottom up mannerfor(inti=0;i<=m;i++){for(intj=0;j<=n;j++){// If first string is empty, only option is to// insert all characters of second stringif(i==0)dp[i][j]=j;// Min. operations = j// If second string is empty, only option is to// remove all characters of second stringelseif(j==0)dp[i][j]=i;// Min. operations = i// If last characters are same, ignore last char// and recur for remaining stringelseif(str1[i-1]==str2[j-1])dp[i][j]=dp[i-1][j-1];// If the last character is different, consider// all possibilities and find the minimumelsedp[i][j]=1+min(dp[i][j-1],dp[i-1][j],dp[i-1][j-1]);}}returndp[m][n];}// Driver codeintmain(){// your code goes herestringstr1="LOVE";stringstr2="MOVIE";cout<<editDistDP(str1,str2,str1.length(),str2.length());return0;}
Java
publicclassMain{// Utility function to find the minimum of three numbersstaticintmin(intx,inty,intz){returnMath.min(Math.min(x,y),z);}staticinteditDistDP(Stringstr1,Stringstr2,intm,intn){// Create a table to store results of subproblemsint[][]dp=newint[m+1][n+1];// Fill dp[][] in bottom-up mannerfor(inti=0;i<=m;i++){for(intj=0;j<=n;j++){// If first string is empty, only option is to// insert all characters of second stringif(i==0)dp[i][j]=j;// Min. operations = j// If second string is empty, only option is to// remove all characters of second stringelseif(j==0)dp[i][j]=i;// Min. operations = i// If last characters are same, ignore last char// and recur for remaining stringelseif(str1.charAt(i-1)==str2.charAt(j-1))dp[i][j]=dp[i-1][j-1];// If the last character is different, consider// all possibilities and find the minimumelsedp[i][j]=1+min(dp[i][j-1],dp[i-1][j],dp[i-1][j-1]);}}returndp[m][n];}publicstaticvoidmain(String[]args){Stringstr1="LOVE";Stringstr2="MOVIE";System.out.println(editDistDP(str1,str2,str1.length(),str2.length()));}}// This code is contributed by shivamgupta0987654321
Python3
# Utility function to find the minimum of three numbersdefminimum(x,y,z):returnmin(x,min(y,z))defeditDistDP(str1,str2,m,n):# Create a table to store results of subproblemsdp=[[0]*(n+1)for_inrange(m+1)]# Fill dp[][] in bottom-up mannerforiinrange(m+1):forjinrange(n+1):# If first string is empty, only option is to# insert all characters of second stringifi==0:dp[i][j]=j# Min. operations = j# If second string is empty, only option is to# remove all characters of second stringelifj==0:dp[i][j]=i# Min. operations = i# If last characters are same, ignore last char# and recur for remaining stringelifstr1[i-1]==str2[j-1]:dp[i][j]=dp[i-1][j-1]# If the last character is different, consider# all possibilities and find the minimumelse:dp[i][j]=1+minimum(dp[i][j-1],dp[i-1][j],dp[i-1][j-1])returndp[m][n]if__name__=="__main__":str1="LOVE"str2="MOVIE"print(editDistDP(str1,str2,len(str1),len(str2)))
JavaScript
// Utility function to find the minimum of three numbersfunctionmin(x,y,z){returnMath.min(Math.min(x,y),z);}functioneditDistDP(str1,str2,m,n){// Create a table to store results of subproblemsletdp=Array(m+1).fill().map(()=>Array(n+1).fill(0));// Fill dp[][] in bottom-up mannerfor(leti=0;i<=m;i++){for(letj=0;j<=n;j++){// If first string is empty, only option is to// insert all characters of second stringif(i==0)dp[i][j]=j;// Min. operations = j// If second string is empty, only option is to// remove all characters of second stringelseif(j==0)dp[i][j]=i;// Min. operations = i// If last characters are same, ignore last char// and recur for remaining stringelseif(str1.charAt(i-1)==str2.charAt(j-1))dp[i][j]=dp[i-1][j-1];// If the last character is different, consider// all possibilities and find the minimumelsedp[i][j]=1+min(dp[i][j-1],dp[i-1][j],dp[i-1][j-1]);}}returndp[m][n];}letstr1="LOVE";letstr2="MOVIE";console.log(editDistDP(str1,str2,str1.length,str2.length));
Output
2
Time Complexity: O(n * m), where n and m are the length of input strings. Auxiliary Space: O(n * m)