【力扣】【72】【中等】编辑距离
作者:shizhishi |
发布时间: |
分类:算法精解 |
声明:个人技术博客 • 非官方 • 仅供技术学习交流
我们需要找到最短的步数,这里用 **动态规划** 的方法做 * 第一行代表空字符变为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 | | | | | |
| 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];
}
}
```