动态规划解题思路
难度在于定义最优解的结构。
根据动态规划思想容易定义出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] 代表 word1 到 i 位置转换成 word2 到 j 位置需要最少步数
所以,
当 word1[i] == word2[j],dp[i][j] = dp[i-1][j-1];
当 word1[i] != word2[j],dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1
其中,dp[i-1][j-1] 表示替换操作,dp[i-1][j] 表示删除操作,dp[i][j-1] 表示插入操作。
解题代码
/**
* 动态规划
* 计算编辑距离
*/
public int minDistance(String word1, String word2) {
// 分析优化解的结构
// 递归定义最优解的代价
// 自顶向上地计算优化解的代价
// 求解最优解
int m1 = word1.length();
int m2 = word2.length();
int[][] dp = new int[m1+1][m2+1];
for(int i=0;i<=m1;i++){
dp[i][0] = i;
}
for(int j=0;j<=m2;j++){
dp[0][j] = j;
}
for(int i=1;i<=m1;i++){
for(int j=1;j<=m2;j++){
if(word1.charAt(i-1) == word2.charAt(j-1)) {
dp[i][j] = dp[i-1][j - 1];
}else {
dp[i][j] = 1 + Math.min(Math.min(dp[i-1][j-1],dp[i-1][j]),dp[i][j-1]);
//dp[i-1][j-1]到dp[i][j]需要进行替换操作,dp[i-1][j]到d[i][j]需要进行删除操作
//dp[i][j-1] 到d[i][j]需要进行添加操作。
}
}
}
return dp[m1][m2];
}