【LeetCode-动态规划】编辑代价
题目描述
给定两个字符串str1和str2,再给定三个整数ic,dc和rc,分别代表插入、删除和替换一个字符的代价,请输出将str1编辑成str2的最小代价。
示例:
输入:"abc","adc",5,3,2
输出:2
思路
这题是编辑距离的拓展版,在“编辑距离”中只要求求次数,而这个要求代价。当 3 种操作的代价都为 1 时,“编辑代价”就变成了“编辑距离”。注意,这题输出的是将str1编辑成str2的最小代价。
- 状态定义:dp[i][j] 表示 str[0,...,i-1] 到 str[0,...,j-1] 的最小代价;
- 状态转移:dp[i][j] 可以从 dp[i-1][j]、dp[i][j-1] 和 dp[i-1][j-1] 转化而来,和“编辑距离”类似,我们设置 3 个变量:a = dp[i-1][j] + dc, b = dp[i][j-1] + ic,c 从 dp[i-1][j-1] 推导而来,要分情况讨论:str1[i-1]==str2[j-1] 时,c = dp[i-1][i-1],否则 c = dp[i-1][j-1] + rc,然后 dp[i][j] = min(a, b, c);
- 边界条件:dp[0][j] = ic * j 表示要向 str1 中插入 j 个字符,dp[i][0] = dc * j,表示要删除 str1 的 i 个字符。
代码如下:
class Solution {
public:
/**
* min edit cost
* @param str1 string字符串 the string
* @param str2 string字符串 the string
* @param ic int整型 insert cost
* @param dc int整型 delete cost
* @param rc int整型 replace cost
* @return int整型
*/
int minEditCost(string str1, string str2, int ic, int dc, int rc) {
int m = str1.size();
int n = str2.size();
vector<vector<int>> dp(m+1, vector<int>(n+1, 0));
for(int i=0; i<=m; i++) dp[i][0] = i * dc; // 将str1逐个删除字符直到str1变成空串
for(int j=0; j<=n; j++) dp[0][j] = j * ic; // 将空串str1逐个插入字符直到变成str2
for(int i=1; i<=m; i++){
for(int j=1; j<=n; j++){
int a = dp[i-1][j] + dc;
int b = dp[i][j-1] + ic;
int c = dp[i-1][j-1];
if(str1[i-1]!=str2[j-1]) c += rc;
dp[i][j] = min(a, min(b, c));
}
}
return dp[m][n];
}
};
- 时间复杂度:O(m*n)
- 空间复杂度:O(m*n)
参考
1、https://www.cnblogs.com/Lee-yl/p/9977822.html
2、http://blog.xbblfz.site/2018/05/14/LeetCode刷题思路/#mineditcost