72. 编辑距离

  1. 题目链接

  2. 解题思路

    • 直接暴力递归,process(i, j)word1[i...]转换成word2[j...]需要的最少操作次数,也就是说,i字符之前的不用处理了,已经变成了j字符之前的了。
    • 如果word1[i] == word2[j]
      • 可以什么操作都不干,i和j就完成了,所以返回process(i + 1, j + 1)
      • 也可以插入一个字符word2[j],所以返回process(i, j + 1) + 1,注意这里操作了一次要加1.
      • 也可以删除一个字符,所以返回process(i + 1, j) + 1
    • 如果word1[i] != word2[j]
      • 可以替换成word2[j],所以返回process(i + 1, j + 1) + 1
      • 可以插入一个字符word2[j],所以返回process(i, j + 1) + 1
      • 可以删除一个字符,所以返回process(i + 1, j) + 1
    • 为了写代码好看,可以在相等的时候,也加一个「替换字符」的操作(虽然替换字符的操作肯定是不会是最优解)。
    • 递归函数,两个可变参数,所以直接加缓存就行,这就是「自顶向下」的动态规划。
  3. 代码

    class Solution {
    public:
    int process(const string& s1, const string &s2, int i, int j, vector<vector<int>> &dp) {
    if (i == s1.size() && j == s2.size()) { // 都到结尾了 不需要操作了 返回0
    return 0;
    }
    if (i == s1.size()) { // 只能在后面加字符了
    return s2.size() - j;
    }
    if (j == s2.size()) { // 只能把后面的字符删除了
    return s1.size() - i;
    }
    if (dp[i][j] != -1) {
    return dp[i][j];
    }
    // 删除操作
    int del_res = process(s1, s2, i + 1, j, dp) + 1;
    // 插入操作
    int insert_res = process(s1, s2, i, j + 1, dp) + 1;
    // 替换操作
    int replace_res = process(s1, s2, i + 1, j + 1, dp) + 1;
    int do_nothing = INT32_MAX; // 这种情况不一定有 相等的时候才有
    if (s1[i] == s2[j]) {
    do_nothing = process(s1, s2, i + 1, j + 1, dp);
    }
    dp[i][j] = min(del_res, min(insert_res, min(replace_res, do_nothing)));
    return dp[i][j];
    }
    int minDistance(string word1, string word2) {
    int n = word1.size();
    int m = word2.size();
    vector<vector<int>> dp(n, vector<int>(m, -1));
    return process(word1, word2, 0, 0, dp);
    }
    };
posted @   ouyangxx  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示