Problem description:

Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2.

You have the following 3 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’)

Analysis:

This problem can be solved with dynamic programming. If the length of original word and target word are l1 and l2 respectively, then we first construct a matrix dp. Each element in the matrix dp[i][j] represents a subproblem, which means the minimum number of steps it takes to convert from first i letters of word 1 to first j letters of word 2.

Subproblem relationship from bottom up:

If the i-th letter in word 1 is equal to j-th letter in word 2, then dp[i][j] equals to dp[i - 1][j - 1], because we don’t have to make any action on this letter. If the two letters are not the same, then we have to perform one action:

  1. delete: dp[i][j] = dp[i - 1][j] + 1
  2. insert: dp[i][j] = dp[i][j - 1] + 1
  3. replace: dp[i][i] = dp[i - 1][j - 1] + 1

Then we choose the minimum number among the three options.
The result would be dp[l2][l1].

Here’s a link of an excellent video explanation:
https://www.youtube.com/watch?v=MiqoA-yF-0M

Java Code:

EditDistance.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class EditDistance {
public int minDistance(String word1, String word2) {
int l1 = word1.length();
int l2 = word2.length();
int[][] dp = new int[l2 + 1][l1 + 1];
for (int i = 0; i < l2 + 1; i++) {
dp[i][0] = i;
}
for (int i = 0; i < l1 + 1; i++) {
dp[0][i] = i;
}

for (int i = 1; i < l2 + 1; i++) {
for (int j = 1; j < l1 + 1; j++) {
if (word2.charAt(i - 1) == word1.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1]));
}
}
}
return dp[l2][l1];
}
}