题目描述:
解法:动态规划
动态规划解题主要步骤:
- 确定dp数组以及下标含义
- 推出递推公式
- 初始化
- 确定遍历顺序
本题分析如下 :
- 确定dp数组以及下标含义:dp[1] [j] 表示 [0, i - 1]的word1 和 [0, j - 1] 的word2的最小编辑操作为dp[i] [j]
- 递推公式:
(1) 如果 word1[i - 1] == word2[j - 1] 相等的话就什么也不用操作了,则dp[i] [j] = dp[i - 1] [j - 1]
(2) 如果 word1[i - 1] != word2[j - 1]
1.删除操作:
- 删除word1[i - 1]
dp[i] [j] = dp[i - 1] [j] + 1, dp[i - 1] [j] 表示[0, i - 2]的word1,因为这里是删除word1[i - 1],
- 删除word2[j - 1]
dp[i] [j] = dp[i] [j - 1] + 1
2. 替换操作:
- 将word1[i - 1] = word2[j - 1],
dp[i] [j] = dp[i - 1] [j - 1] + 1
插入操作和删除操作一样,
如: word1 = cd , word2 = c, 删除word1[1] 后word1 = c。插入word2[1] = d后word2 = cd 效果一样。
- 初始化dp数组
从递推公式可以看出dp[i] [j] 是由 dp[i - 1] [j - 1] 推导而来,所以 dp[0] [j] 和 dp[i] [0] 需要初始化。dp[0] [j] = j, dp[i] [0] = i 即可。
- 确定遍历顺序
从前往后,从上到下
代码:
class Solution {
public int minDistance(String word1, String word2) {
int l1 = word1.length(), l2 = word2.length();
int[][] dp = new int[l1 + 1][l2 + 1];
for(int i = 0; i <= l1; i++){
dp[i][0] = i;
}
for(int j = 0; j <= l2; j++){
dp[0][j] = j;
}
for(int i = 1; i <= l1; i++){
for(int j = 1; j <= l2; 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] + 1), dp[i - 1][ j - 1] + 1);
}
}
}
return dp[l1][l2];
}
}