【LeetCode-动态规划】编辑代价

题目描述

给定两个字符串str1和str2,再给定三个整数ic,dc和rc,分别代表插入、删除和替换一个字符的代价,请输出将str1编辑成str2的最小代价。
示例:

输入:"abc","adc",5,3,2
输出:2

题目链接: https://www.nowcoder.com/questionTerminal/05fed41805ae4394ab6607d0d745c8e4?orderByHotValue=1&questionTypes=001110&page=2&onlyReference=false

思路

这题是编辑距离的拓展版,在“编辑距离”中只要求求次数,而这个要求代价。当 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

posted @ 2020-09-01 16:29  Flix  阅读(881)  评论(0编辑  收藏  举报