美文网首页
72. Edit Distance

72. Edit Distance

作者: RobotBerry | 来源:发表于2017-05-10 20:49 被阅读0次

    问题

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

    You have the following 3 operations permitted on a word:

    a) Insert a character
    b) Delete a character
    c) Replace a character

    例子

    abc bad
    3

    分析

    最优化问题 + 大问题可以用小问题来解决 => 动态规划

    1. 状态表
      dp[i][j] word1[0, i-1]转化为word2[0, j-1]的最小步数

    2. 初始状态
      dp[0][0] = 0 空串=空串,不需要转化;
      dp[i][0] = i, i >= 1 长度为i的字符串转化为空串,需要添加i个字符串;
      dp[0][j] = j, j >= 1 空串转化为长度为j的字符串,需要删除i个字符串。

    3. 状态转移方程
      dp[i][j] = dp[i - 1][j - 1], if word1[i - 1] == word2[j - 1]
      注:当word1的第i个字符和word2的第j个字符相等时, word1[0, i-1]转化为word2[0, j-1]的最小步数等于word1[0, i-2]转化为word2[0, j-2]的最小步数
      dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1, if word1[i - 1] != word2[j - 1]
      注:当word1的第i个字符和word2的第j个字符不相等时,word1可以先转换、删除第i个字符,或者在word2添加第j个字符,然后再进一步转化为word2。第一步都需要1次转化,第二步分别需要dp[i - 1][j - 1]、dp[i - 1][j]和dp[i][j - 1]次转化。取最小值即可。

    要点

    dp

    时间复杂度

    O(mn)

    空间复杂度

    O(mn)

    代码

    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));
            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], min(dp[i - 1][j], dp[i][j - 1])) + 1;
                }
            } 
            return dp[m][n];
        }
    };
    

    空间复杂度为O(2n)的代码

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

    空间复杂度为O(n)的代码

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

    相关文章

      网友评论

          本文标题:72. Edit Distance

          本文链接:https://www.haomeiwen.com/subject/rwagtxtx.html