1. 程式人生 > 實用技巧 >【LeetCode-動態規劃】編輯代價

【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 時,“編輯代價”就變成了“編輯距離”。

  • 狀態定義: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;
        for(int j=0; j<=n; j++) dp[0][j] = j * ic;
        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