72.编辑距离

72.编辑距离

题目:https://leetcode.cn/problems/edit-distance

思路

最难的是得到这个递推方程式,具体可以看 最长公共子序列 编辑距离【基础算法精讲 19】

注意这里的边界条件,当 i=0 时,需要操作 j+1 次;当 j=0 时,需要操作 i+1 次。

回溯写法

class Solution {
public:
    int minDistance(string word1, string word2) {
        int n = word1.length(), m = word2.length();
        auto dfs = [&](this auto&& dfs, int i, int j) -> int {
            if (i < 0) {
                return j + 1;
            }
            if (j < 0) {
                return i + 1;
            }
            if (word1[i] == word2[j]) {
                return dfs(i - 1, j - 1);
            }
            return min({dfs(i, j - 1), dfs(i - 1, j), dfs(i - 1, j - 1)}) + 1;
        };
        return dfs(n - 1, m - 1);
    }
};

回溯写法+记忆化搜索

class Solution {
public:
    int minDistance(string word1, string word2) {
        int n = word1.length(), m = word2.length();
        vector memo(n, vector<int>(m, -1));

        auto dfs = [&](this auto&& dfs, int i, int j) -> int {
            if (i < 0) {
                return j + 1;
            }
            if (j < 0) {
                return i + 1;
            }
            
            int& res = memo[i][j];
            if (res != -1) {
              return res;
            }

            if (word1[i] == word2[j]) {
                return res = dfs(i - 1, j - 1);
            }
            return res = min({dfs(i, j - 1), dfs(i - 1, j), dfs(i - 1, j - 1)}) + 1;
        };
        return dfs(n - 1, m - 1);
    }
};

回溯改为递推

class Solution {
public:
    int minDistance(string word1, string word2) {
        int n = word1.length(), m = word2.length();
        vector f(n + 1, vector<int>(m + 1));

        for (int i = 0; i < n; i++) {
          f[i + 1][0] = i + 1;
        }
        for (int j = 0; j < m; j++) {
          f[0][j + 1] = j + 1;
        }

        for (int i = 0; i < n; i++) {
          for (int j = 0; j < m; j++) {
            if (word1[i] == word2[j]) {
              f[i + 1][j + 1] = f[i][j];
            } else {
              f[i + 1][j + 1] = min({f[i + 1][j], f[i][j + 1], f[i][j]}) + 1;
            }
          }
        }

        return f[n][m];
    }
};