leetcode 72 编辑距离
题目:https://leetcode-cn.com/problems/edit-distance/
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数。 你可以对一个单词进行如下三种操作: 插入一个字符 删除一个字符 替换一个字符 0 <= word1.length, word2.length <= 500 word1 和 word2 由小写英文字母组成
思路:
首先一般这种求最值的问题都要想到动态规划。怎么定义状态和转移方程?
状态定义:
dp[i][j] 表示从word1的前i个字符转换成word2的前j个字符的最少操作数。
状态转移,有三种操作可以得到dp[i][j]:
替换:dp[i][j] = dp[i - 1][j - 1] + (word1[i] == word2[j] ? 0 : 1); 将word1的第i个字符替换为word2的第j个字符,若word1[i] == word2[j],则不用替换。
增:dp[i][j] = dp[i][j - 1] + 1; 即:从word1的前i个字符变成word2的前j - 1个字符后,增加word2第j个字符。
删:dp[i][j] = dp[i - 1][j] + 1; 即:从word1的前i - 1个字符变成word2的前j个字符后,删除word2第j个字符。
因为求的是最少操作数,所以,
dp[i][j] = min(min(dp[i - 1][j - 1] + (word1[i] == word2[j] ? 0 : 1), dp[i][j - 1] + 1), dp[i - 1][j] + 1);
最后答案为dp[n][m]; n为word1的长度,m为word2的长度。
class Solution {
public:
int minDistance(string word1, string word2) {
int n = word1.size(), m = word2.size();
// dp[i][j] 表示从word1的前i个字符变成word2需要的最少操作
vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
for(int i = 1; i <= n; i++) {
dp[i][0] = i;
}
for(int j = 1; j <= m; j++) {
dp[0][j] = j;
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
// 替换
if(word1[i - 1] == word2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
}
else {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
// 删,增
dp[i][j] = min(min(dp[i][j], dp[i - 1][j] + 1), dp[i][j - 1] + 1);
// cout << i << " " << j << " " << dp[i][j] << endl;
}
}
return dp[n][m];
}
};


浙公网安备 33010602011771号