1 题目
动态规划参考:算法-动态规划-《算法导论3rd-P215》_hclbeloved的博客-CSDN博客
2 分析
(1)使用从底向上的动态规划(此时是需要base case的);
(2)确定dp的含义:dp[i][j]表示字符串A的前i个字母到字符串B的前j个字母间的最少编辑距离。
(3)base case:dp[i][0] = i, dp[0][j] = j
(4)状态转移方程:
(4.1)已知dp[i][j-1],则在A字符串的前i个字符后面插入B[j]就可以变成B字符串的前j个字符,即dp[i][j] = dp[i][j-1] + 1;
(4.2)已知dp[i-1][j],则删除A字符串中的A[i],就可以变成B字符串的前j个字符,即dp[i][j] = dp[i-1][j] + 1;
(4.3)已知dp[i-1][j-1],若A[i] == B[j],则 dp[i][j] = dp[i-1][j-1],也就是不用任何额外的操作;若A[i] != B[j],则需要一次额外的替换操作,将B[j]赋值给A[j]即可,即:dp[i][j] = dp[i-1][j-1] + 1;
3 代码实现
//https://leetcode-cn.com/problems/edit-distance/solution/bian-ji-ju-chi-by-leetcode-solution/
class Solution {
public:
int minDistance(string word1, string word2) {
int n = word1.length();
int m = word2.length();
// 有一个字符串为空串
if (n * m == 0) return n + m;
// DP 数组
int dp[n + 1][m + 1];
// 边界状态初始化
for (int i = 0; i <= n; i++)
{
dp[i][0] = i;
}
for (int j = 0; j <= m; j++)
{
dp[0][j] = j;
}
// 计算所有 DP 值
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (word1[i - 1] == word2[j - 1])
dp[i][j] = std::min(dp[i-1][j-1], std::min(1+dp[i-1][j], 1+dp[i][j-1]));
else
dp[i][j] = std::min(1+dp[i-1][j-1], std::min(1+dp[i-1][j], 1+dp[i][j-1]));
}
}
return dp[n][m];
}
};