1. 程式人生 > >LeetCode 72-Edit Distance(動態規劃)

LeetCode 72-Edit Distance(動態規劃)

本題為經典的動態規劃。解決本題的前提是把這題的動態方程先搞明白。

題目:(動態規劃)https://leetcode.com/problems/edit-distance/

概述:給定兩個單詞,給了三種方法(替換,刪除,插入),用這三種方法使得兩個單詞相同。

思路:採用動態規劃。要實現動態方程,我們需要考慮兩種情況:①邊緣情況 ②一般情況

  1. 邊緣情況:
    轉化word1[0…i - 1] 到 “” 至少要進行一次刪除,word2[0…i - 1]到 “” 同理。
    dp[i][0] = i;
    dp[0][j] = j;

  2. 一般情況:
    對於兩個非空的字串,我們需要把這些問題分解為子問題,假設我們知道如何去轉換word1[0…i - 2] 到 word2[0…j - 2],也就是知道了dp[i - 1][j - 1]。

    如果word1[i - 1] == word2[i - 1]
    那麼從上一步dp[i - 1][j - 1] 到 dp[i][j] 不用進行任何操作,即dp[i][j] = dp[i - 1][j - 1]。

    否則word1[i - 1] != word2[i - 1]

    考慮以下三種情況:

    1. 替換 word1[i - 1] 用 word2[j - 1] (dp[i][j] = dp[i - 1][j - 1] + 1);
    2. 刪除 word1[i - 1] 使得 word1[0…i - 2] == word2[0…j - 1] (dp[i][j] = dp[i - 1][j] + 1);
    3. 把 word2[j - 1] 插入word1[0…i - 1] 使得 word1[0…i - 1] + word2[j - 1] == word2[0…j - 1] (dp[i][j] = dp[i][j - 1] + 1).

綜上所述,我們得到了這樣的方程:

dp[i][0] = i;
dp[0][j] = j;
dp[i][j] = dp[i - 1][j - 1], if word1[i - 1] = word2[j - 1];
dp[i][j] = min(dp[i - 1][j - 1] + 1, dp[i - 1][j] + 1, dp[i][j - 1
] + 1), otherwise.

這裡附上程式碼:

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.length(), n = word2.length();
        vector<vector<int> > dp(m + 1, vector<int> (n + 1, 0));
        for (int i = 1; i <= m; i++)
            dp[i][0] = i;
        for (int j = 1; 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] + 1, min(dp[i][j - 1] + 1, dp[i - 1][j] + 1));
            }
        }
        return dp[m][n];
    }
};