@(labuladong的算法小抄)[dp]
leetcode 72. 编辑距离
题目描述
解题思路
参考:经典动态规划:编辑距离
对“dp[i-1][j-1] 表示替换操作,dp[i-1][j] 表示删除操作,dp[i][j-1] 表示插入操作。”的补充理解:
以 word1 为 “horse”,word2 为 “ros”,且 dp[5][3] 为例,即要将 word1的前 5 个字符转换为 word2的前 3 个字符,也就是将 horse 转换为 ros,因此有:
(1) dp[i-1][j-1],即先将 word1 的前 4 个字符 hors 转换为 word2 的前 2 个字符 ro,然后将第五个字符 word1[4](因为下标基数以 0 开始) 由 e 替换为 s(即替换为 word2 的第三个字符,word2[2])
(2) dp[i][j-1],即先将 word1 的前 5 个字符 horse 转换为 word2 的前 2 个字符 ro,然后在末尾补充一个 s,即插入操作
(3) dp[i-1][j],即先将 word1 的前 4 个字符 hors 转换为 word2 的前 3 个字符 ros,然后删除 word1 的第 5 个字符
class Solution {
public int minDistance(String word1, String word2) {
int m = word1.length(), n = word2.length();
/* 如果一个字符串为空,则需要直接把另一个字符串全部删除,编辑距离等于字符串长度 */
if(m == 0) return n;
if(n == 0) return m;
/* dp[i][j]表示 word1[0...i-1] 和 word2[0...j-1] 的最小编辑距离 */
int[][] dp = new int[m + 1][n + 1];
/* base case:dp[i][0] = i, dp[0][j] = j*/
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 {
dp[i][j] = 1 + min(
dp[i - 1][j], //删除
dp[i][j - 1], //增加
dp[i - 1][j - 1] //替换
);
}
}
}
/* 返回word1[0...m-1] 和 word2[0...n-1] 的最小编辑距离 */
return dp[m][n];
}
/* 返回三个整数的最小值 */
private int min (int a, int b, int c) {
return Math.min(a, Math.min(b, c));
}
}