Day56 动规 LC 583 72

65 阅读1分钟

583. 两个字符串的删除操作

心得

  • 想的是求最长公共子序列,然后两个size之和减去2倍即可,

题解

  • 直接按照题意列dp更容易
  • 考虑当前相等与否,不等删ab的情况

class Solution {
public:
    int minDistance(string word1, string word2) {
        // dp[i][j] 表示以i-1结尾的word1和j-1结尾的word2删除相同需要的最小步数
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, 0));
        // 0表示空串,删到空串需要i次(元素个数)
        for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;
        for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;
        for (int i = 1; i <= word1.size(); i++) {
            for (int j = 1; j <= word2.size(); 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, dp[i][j - 1] +  1, dp[i - 1][j - 1] + 2);优化
                    dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] +  1);
                }
                 
            }
        }
        return dp[word1.size()][word2.size()];
    }
};

// 最大公共子串作差法
class Solution {
public:
    int minDistance(string word1, string word2) {
				// dp[i][j] 表示以i-1结尾的word1和j-1结尾的word2的最大公共子序列长度
        vector<vector<int>> dp(word1.size()+1, vector<int>(word2.size()+1, 0));
        for (int i=1; i<=word1.size(); i++){
            for (int j=1; j<=word2.size(); j++){
                if (word1[i-1] == word2[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
                else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
            }
        }
        return word1.size()+word2.size()-dp[word1.size()][word2.size()]*2;
    }
};

72. 编辑距离

心得

题解

  • 重点考虑不等情况下的三种操作,即增删改,其他逻辑与前一致,增加的逻辑被涵盖在删除中
  • 新增等同于删,如ab和a,a增加和ab删除效果一样,所以含在删除中
  • 其他即删a删b
class Solution {
public:
    int minDistance(string word1, string word2) {
        // dp[i][j] 表示以i-1结尾的word1和j-1结尾的word2转换的最小步数
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, 0));
        // 0表示空串,删到空串需要i次(元素个数)
        for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;
        for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;
        for (int i = 1; i <= word1.size(); i++) {
            for (int j = 1; j <= word2.size(); j++) {
                if (word1[i - 1] == word2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    // 删ab,新增等同于删,如ab和a,a增加和ab删除效果一样,所以含在删除中
                    dp[i][j] = min({dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]}) + 1;
                }
                 
            }
        }
        return dp[word1.size()][word2.size()];
    }
};