1. 程式人生 > >LeetCode 72.Edit Distance (編輯距離)

LeetCode 72.Edit Distance (編輯距離)

題目:

給定兩個單詞 word1 和 word2,計算出將 word1 轉換成 word2 所使用的最少運算元 。

你可以對一個單詞進行如下三種操作:

  1. 插入一個字元
  2. 刪除一個字元
  3. 替換一個字元

示例 1:

輸入: word1 = "horse", word2 = "ros"
輸出: 3
解釋: 
horse -> rorse (將 'h' 替換為 'r')
rorse -> rose (刪除 'r')
rose -> ros (刪除 'e')

示例 2:

輸入: word1 = "intention", word2 = "execution"
輸出: 5
解釋: 
intention -> inention (刪除 't')
inention -> enention (將 'i' 替換為 'e')
enention -> exention (將 'n' 替換為 'x')
exention -> exection (將 'n' 替換為 'c')
exection -> execution (插入 'u')

 

思路:
如果沒有替換,只是簡單的增加和刪除的話,那麼可以用一個最長公共子序列去做,找到最長的公共字串,然後用len1+len2-2*公共子序列長度。

然而這裡有替換,有替換的話,情況就發生了變化,因為有時候替換一個比的上新增或刪除兩個。

定義狀態:dp[i][j]:第一個串的第i個位置與第二個串的第j個位置之前需要操作幾次達到相等。

之後,如果word1[i] = word2[j],如果相等的話,那麼就不用替換,也不要增刪,操作次數直接等於dp[i-1][j-1]。

如果不等於,需要考慮三種情況:

插入:在word1[i-1]的位置上插入word2[j-1],也就是說word1[0...i-1]=word2[0...j-1],dp[i][j]=dp[i][j-1]+1
替換:將word1[i-1]的值替換為word2[j-1]。dp[i][j]=dp[i-1][j-1]+1
刪除:將word1[i-1]的值刪除使word1[0...i-2]等價於word2[j-1], dp[i][j] = dp[i-1][j]+1

那麼轉移方程為:dp[i][j] = min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1;

有一個錯誤的認識就是,如果一個長串和一個短串比較,如果刪只能刪當前較長的串,這種認識是錯誤的,舉個例子:

sma和uism,對這種情況,顯然必須刪除短串的最後一個字元,因為它礙著sm的匹配了。
 

 

AC C++ Solution:

class Solution {
public:
    int minDistance(string word1, string word2) {
        
        int m = word1.size(), n = word2.size();
        vector<vector<int>> dp(m+1, vector<int>(n+1, 0));
        // int dp[m+1][n+1];
        
        for(int i = 0; i <= m; i++)
        {
            dp[i][0] = i;
        }
        
        for(int j = 0; j <= n; j++)
        {
            dp[0][j] = j;
        }
        
        for(int i = 1; i <= m; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                if(word1[i-1] == word2[j-1])
                {
                    dp[i][j] = dp[i-1][j-1];
                }
                else
                {
                    dp[i][j] = min(dp[i-1][j-1], min(dp[i][j-1], dp[i-1][j])) + 1;
                }
            }
        }
        return dp[m][n];
    }
};