- Leetcode (72): Edit Distance
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')
- Input
- 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')
- Input
-
Solution 1: Recursion
- Idea
- Use 2 pointers
iandjto points1ands2respectively. - Compare each char from right to left.
- Base cases:
- If
ifinishes, it means all the chars ins2[0 ... j]should be deleted. So it needsj+1delete operations. - If
jfinishes, it means all the chars ins1[0 ... i]should be deleted. So it needsi+1delete operations.
- If
- For
s1[i]ands2[j]- If
s1[i] = s2[j], no operation is needed, moveiandjto the next char respectively. - If
s1[i] != s2[j], enumerate 3 possible choices, get the minimum operations from 3 choices.
- If
- Use 2 pointers
- Complexity
- Time complexity: O(3M) (M is the max length between
word1andword2)
- Time complexity: O(3M) (M is the max length between
class Solution { public int minDistance(String word1, String word2) { return recursion(word1, word2, word1.length()-1, word2.length()-1); } int recursion(String s1, String s2, int i, int j) { if (i == -1) return j+1; if (j == -1) return i+1; if (s1.charAt(i) == s2.charAt(j)) { return recursion(s1, s2, i-1, j-1); // do nothing } else { return min( recursion(s1, s2, i, j-1)+1, // insert recursion(s1, s2, i-1, j)+1, // delete recursion(s1, s2, i-1, j-1)+1 // replace ); } } int min(int i1, int i2, int i3) { return Math.min(i1, Math.min(i2, i3)); } }
- Idea
-
Solution 2: Dynamic programming
- Idea
dp[i][j]is the edit distance betweens1[0 ... i-1]ands2[0 ... j-1].- Base cases:
- Initialize
dp[i][0]asi. - Initialize
dp[0][j]asj.
- Initialize
- State transition equation
if s1[i] == s2[j]: dp[i][j] = dp[i-1][j-1] else dp[i][j] = min ( dp[i][j-1], // delete dp[i-1][j], // insert dp[i-1][j-1] // replace )
class Solution { public int minDistance(String s1, String s2) { int m = s1.length(), n = s2.length(); int[][] dp = new int[m + 1][n + 1]; // base case for (int i = 1; i <= m; i++) dp[i][0] = i; for (int j = 1; j <= n; j++) dp[0][j] = j; // bottom-up calculation 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]; else dp[i][j] = min( dp[i - 1][j] + 1, // delete dp[i][j - 1] + 1, // insert dp[i - 1][j - 1] + 1 // replace ); // final result will be the i=m and j=n return dp[m][n]; } int min(int a, int b, int c) { return Math.min(a, Math.min(b, c)); } }
- Idea