核心思路
dp[i][j]:把word1前i个字符 → 变成word2前j个字符,最少操作数- 三种操作对应三种来源:
- 替换 :
dp[i-1][j-1] + 1 - 删除 :
dp[i-1][j] + 1 - 插入 :
dp[i][j-1] + 1
- 替换 :
- 如果字符相等 ,就不用操作:
dp[i][j] = dp[i-1][j-1]
通俗解释
dp[i][0] = i:word2 为空,word1 要删 i 次dp[0][j] = j:word1 为空,要插 j 次
字符不同时:
- 替换 :把 word1 第 i 个换成 word2 第 j 个→ 前面
i-1,j-1+ 1 次 - 删除 :删掉 word1 第 i 个→ 前面
i-1,j+ 1 次 - 插入 :给 word1 插一个字符→ 前面
i,j-1+ 1 次
三者取最小就是当前最优
完整代码实现:
class Solution {
public int minDistance(String word1, String word2) {
int m = word1.length();
int n = word2.length();
int[][] dp = new int[m + 1][n + 1];
// 初始化:一个为空,另一个全删/全插
for (int i = 0; i <= m; i++) dp[i][0] = i;
for (int j = 0; j <= n; j++) dp[0][j] = j;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
// 字符相同,不用操作
if (word1.charAt(i-1) == word2.charAt(j-1)) {
dp[i][j] = dp[i-1][j-1];
} else {
// 取替换、删除、插入 三者最小 +1
dp[i][j] = Math.min(
Math.min(dp[i-1][j-1], dp[i-1][j]),
dp[i][j-1]
) + 1;
}
}
}
return dp[m][n];
}
}