题解 | #最小编辑代价#

最小编辑代价

http://www.nowcoder.com/practice/05fed41805ae4394ab6607d0d745c8e4

题解一:动态规划
动态转移方程分析图示:
图片说明

复杂度分析:
时间复杂度:O(MN)
空间复杂度:O(MN)

实现如下:

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) {
        // write code here
        int len1 = str1.size();
        int len2 = str2.size();
        int dp[len1+1][len2+1];
        memset(dp,0,sizeof(dp));
        for(int i = 1;i<=len1;i++) dp[i][0] =i*dc;  // str2 长度为0,只能删除
        for(int i = 1;i<=len2;i++) dp[0][i] = i*ic; // str1 长度为0, 只能插入
        for(int i = 1;i<=len1;i++){
            for(int j = 1;j<=len2;j++){
                if(str1[i-1] == str2[j-1]) dp[i][j] = dp[i-1][j-1];  //r1[i] = str2[j]
                else {
                    dp[i][j] = min(dp[i-1][j-1]+rc,dp[i][j-1]+ic);   //dp[i][j] 取三种措施的最小的代价
                    dp[i][j] = min(dp[i][j],dp[i-1][j]+dc);
                }
            }
        }
        return dp[len1][len2];
    }
};

题解二:滚动数组优化空间复杂度
优化思路: dp[i][j]是从dp[i][j-1]、dp[i-1][j]、dp[i-1][j-1] 转移过来的。 将dp数组变为一维数组之后,那么dp[i][j-1],dp[i-1][j-1]都用dp[j-1]表示,这就造成了冲突。所以使用pre表示dp[i-1][j-1],dp[j-1] = dp[i][j-1],dp[j]表示上一轮的值
复杂度分析:
时间复杂度:O(NM)
空间复杂度: O(N)
实现如下:

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 len1 = str1.size();
            int len2 = str2.size();
            int dp[len2+1];
            memset(dp,0, sizeof(dp));
            //初始化第一行
            for(int i = 1;i<=len2;i++) dp[i] = i*ic;
            for(int i = 1;i<=len1;i++){
                int pre = dp[0];
                dp[0] = i*dc;
                for(int j = 1;j<=len2;++j){
                    int tmp = dp[j];  // 上一轮的dp[i-1][j]
                    if(str1[i-1]==str2[j-1]) dp[j] = pre;
                    else  dp[j] = min(pre+rc,min(dp[j-1]+ic,tmp+dc));
                     pre = tmp;//更新dp[i-1][j-1]
                }
        }
        return dp[len2];
    }
};
牛客网编程题题解 文章被收录于专栏

本专栏记录在牛客网上AC的每一题,写下题解。 未来2年完成2000编程题的题解。 2021.12.29更新,最进准备毕设,断更了,会尽快做完毕设,继续做这一件事情

全部评论
老哥你好,图示中插入str2[j]的那个情况,蓝色的j的位置是不是错了,应该放在 i 后面?
1 回复 分享
发布于 2022-02-14 01:28

相关推荐

不愿透露姓名的神秘牛友
11-20 19:57
已编辑
某大厂 golang工程师 23.0k*16.0, 2k房补,年终大概率能拿到
点赞 评论 收藏
分享
Natrium_:这时间我以为飞机票
点赞 评论 收藏
分享
有趣的牛油果开挂了:最近这个阶段收到些杂七杂八的短信是真的烦
点赞 评论 收藏
分享
13 3 评论
分享
牛客网
牛客企业服务