
我们需要找到最短的步数,这里用 动态规划 的方法做
这里首先处理第一行和第一列
「」 | h | o | r | s | e | |
「」 | 0 | 1 | 2 | 3 | 4 | 5 |
r | 1 | |||||
o | 2 | |||||
s | 3 |
- 第一行代表空字符变为 h/o/r/s/e 的步数为
插入
,并且由于 「h」 处已经插入一次,所以 o 处的步数为 2 - 第一列代表空字符变为 r/o/s 的步数为
删除
,并且由于 「r」 处已经删除一次,所以 o 处的步数为 2
tip : 这里的数字无意义,可以代表任意的删除和插入,这里增加行列只是为了初始化步数。
接着开始推导
「」 | h | o | r | s | e | |
「」 | 0 | 1 | 2 | 3 | 4 | 5 |
r | 1 | 0+1=1 | ||||
o | 2 | |||||
s | 3 |
由于黄色高亮处是初始化后第二步,因此这里由 r 变为 h 的最短步数为:初始化处的0 + 任意操作的 1;
依次类推:
「」 | h | o | r | s | e | |
「」 | 0 | 1 | 2 | 3 | 4 | 5 |
r | 1 | 1 | 2 | 2 | ||
o | 2 | |||||
s | 3 |
由于黄色高亮处的两个字符串都为 r
,所以不用进行任何操作,步数不变,并选择最小值 2
最终
「」 | h | o | r | s | e | |
「」 | 0 | 1 | 2 | 3 | 4 | 5 |
r | 1 | 1 | 2 | 2 | 3 | 4 |
o | 2 | 2 | 1 | 2 | 3 | 4 |
s | 3 | 3 | 2 | 2 | 2 | 3 |
得到结果为 3 ,由于每次算当前步数,都源于对之前字符串处理后的最短步数,因此,这里的 3 就是最短操作数
代码
class Solution {
public int minDistance(String word1, String word2) {
int len1 = word1.length();
int len2 = word2.length();
int[][] dp = new int[len1 + 1][len2 + 1];
// 第一行
for (int j = 1; j <= len2; j++) dp[0][j] = dp[0][j - 1] + 1;
// 第一列
for (int i = 1; i <= len1; i++) dp[i][0] = dp[i - 1][0] + 1;
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) dp[i][j] = dp[i - 1][j - 1];//如果前面的字符串一样,那么这里不用进行任何操作
else dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i][j - 1]), dp[i - 1][j]) + 1;//否则找到最短步数+1
}
}
return dp[len1][len2];
}
}
Comments NOTHING