代码随想录|动态规划|50编辑距离
leetcode:72. 编辑距离 - 力扣(LeetCode)
题目
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
-
插入一个字符
-
删除一个字符
-
替换一个字符
-
示例 1:
-
输入:word1 = "horse", word2 = "ros"
-
输出:3
-
解释: horse -> rorse (将 'h' 替换为 'r') rorse -> rose (删除 'r') rose -> ros (删除 'e')
-
示例 2:
-
输入:word1 = "intention", word2 = "execution"
-
输出:5
-
解释: intention -> inention (删除 't') inention -> enention (将 'i' 替换为 'e') enention -> exention (将 'n' 替换为 'x') exention -> exection (将 'n' 替换为 'c') exection -> execution (插入 'u')
提示:
- 0 <= word1.length, word2.length <= 500
- word1 和 word2 由小写英文字母组成
思路
动归五部曲
(1)dp含义
以[i-1]结尾的word1和以[j-1]结尾的word2,最近的编辑距离是dp[i][j]
(2)递推公式
还是考虑两种情况
- word1[i - 1] == word2[j - 1]
dp[i][j]=dp[i-1][j-1]
- word1[i - 1] != word2[j - 1]
这时候就要考虑3中情况,分别是 增、删、改。
word1增 等价于 word2删,所以有如下改变:
原来是:word1增、删、改 变成word2
现在是:word2删、word1删、word1改 变成word2
word1删:dp[i][j]=dp[i-1][j]+1
word2删:dp[i][j]=dp[i][j-1]+1
word1改:
如果是相同的情况下,那么dp[i][j]=dp[i-1][j-1]
但现在是不同的情况,最后一个字符需要改变,因此dp[i][j]=dp[i-1][j-1]+1
最终取这3个情况的最小值。
(3)dp初始化
跟上面那道题一样,dp[i][0]=i dp[0][j]=j
(4)遍历顺序
跟之前一样。
代码如下:
class Solution
{
public:int minDistance(string word1, string word2){int m = word1.size(), n = word2.size();vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));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[i - 1] == word2[j - 1]){dp[i][j] = dp[i - 1][j - 1];}else{dp[i][j] = min({dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1});}}}return dp[m][n];}
};
总结
编辑距离系列终于搞完了,其实把dp的含义确定之后,再去找递推公式,递推公式一般也是分析两种情况。
参考资料
代码随想录