Given two strings word1 and word2, return the minimum number of operations required to convert word1 to word2.
You have the following three operations permitted on a word:
- Insert a character
- Delete a character
- Replace a character
Example 1:
Input: word1 = “horse”, word2 = “ros”
Output: 3
Explanation:
horse -> rorse (replace ‘h’ with ‘r’)
rorse -> rose (remove ‘r’)
rose -> ros (remove ‘e’)
Example 2:
Input: word1 = “intention”, word2 = “execution”
Output: 5
Explanation:
intention -> inention (remove ‘t’)
inention -> enention (replace ‘i’ with ‘e’)
enention -> exention (replace ‘n’ with ‘x’)
exention -> exection (replace ‘n’ with ‘c’)
exection -> execution (insert ‘u’)
Constraints:
0 <= word1.length, word2.length <= 500word1andword2consist of lowercase English letters.
Approach - Bottom Up
- Use reverse memoization for reference
class Solution {
Integer[][] dp;
public int minDistance(String word1, String word2) {
int m = word1.length(), n = word2.length();
dp = new Integer[m+1][n+1];
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= n; j++) {
if (i == 0 || j == 0)
dp[i][j] = i+j;
else if (word1.charAt(i-1) == word2.charAt(j-1))
dp[i][j] = dp[i-1][j-1];
else
dp[i][j] = 1 + Math.min(dp[i][j-1], Math.min(dp[i-1][j], dp[i-1][j-1]));
}
}
return dp[m][n];
}
}Approach - Memoization
- Just memoize the below solution
- First solution for reverse recursion and second for forward notice how we compare i-1 and j-1 instead of i and j the reason is simple we started from length so we can’t compare them or rather we need to convert it to 0 based this would not be an issue in forward loop as we stop by the time we reach the out of bound
class Solution {
Integer[][] dp;
public int minDistance(String word1, String word2) {
int m = word1.length(), n = word2.length();
dp = new Integer[m+1][n+1];
return solve(word1, word2, m, n);
}
public int solve(String s1, String s2, int i, int j) {
if (i == 0 || j == 0)
return i+j;
if (dp[i][j] != null)
return dp[i][j];
if (s1.charAt(i-1) == s2.charAt(j-1))
return dp[i][j] = solve(s1, s2, i-1, j-1);
else {
int insert = 1 + solve(s1, s2, i, j-1);
int delete = 1 + solve(s1, s2, i-1, j);
int replace = 1 + solve(s1, s2, i-1, j-1);
return dp[i][j] = Math.min(insert, Math.min(delete, replace));
}
}
}class Solution {
Integer[][] dp;
public int minDistance(String word1, String word2) {
dp = new Integer[word1.length()+1][word2.length()+1];
return solve(word1, word2, 0, 0);
}
public int solve(String s1, String s2, int i, int j) {
if (i == s1.length())
return s2.length() - j;
else if (j == s2.length())
return s1.length() - i;
if (dp[i][j] != null)
return dp[i][j];
if (s1.charAt(i) == s2.charAt(j))
return dp[i][j] = solve(s1, s2, i+1, j+1);
else {
int insert = 1 + solve(s1, s2, i, j+1);
int delete = 1 + solve(s1, s2, i+1, j);
int replace = 1 + solve(s1, s2, i+1, j+1);
return dp[i][j] = Math.min(insert, Math.min(delete, replace));
}
}
}Approach - Recursion
- It is simple just think about the options for all three and if matches no need to add 1 also if either is finished then what to do
class Solution {
public int minDistance(String word1, String word2) {
return solve(word1, word2, 0, 0);
}
public int solve(String s1, String s2, int i, int j) {
if (i == s1.length())
return s2.length() - j;
else if (j == s2.length())
return s1.length() - i;
if (s1.charAt(i) == s2.charAt(j))
return solve(s1, s2, i+1, j+1);
else {
int insert = 1 + solve(s1, s2, i, j+1);
int delete = 1 + solve(s1, s2, i+1, j);
int replace = 1 + solve(s1, s2, i+1, j+1);
return Math.min(insert, Math.min(delete, replace));
}
}
}