LeetCode 第55天 | 583. 两个字符串的删除操作 72. 编辑距离 动态规划

583. 两个字符串的删除操作
求两个字符串的最长公共子序列,用两个字符串的长度减去两倍的最长公共子序列长度即为需要进行的最少次数的删除活动。

class Solution {
public:
    int minDistance(string word1, string 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++) {
                // dp整体向右下移动一个
                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()-2*dp[word1.size()][word2.size()];
    }
};

采用代码随想录的方法。一知半解。

class Solution {
public:
    int minDistance(string word1, string word2) {
        vector<vector<int>> dp(word1.size()+1, vector<int>(word2.size()+1, 0));
        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++) {
                // dp[i][j]:以i-1为结尾的字符串word1,
                // 和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最少次数。
                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);
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
};

72. 编辑距离
这个是一类问题,如果word1[i] == word2[j],可以不做修改,dp[i][j] = dp[i-1][j-1];如果 word1[i] != word2[j],则可以两个字符都退一位,替换一个字符;或者word1删除一位;或者word2删除一位;则递推公式为:
dp[i][j] = min({dp[i-1][j-1], dp[i][j-1], dp[i-1][j]}) + 1。删除和添加是一个意思,相当于进行一次操作,可以是删除也可以是增加。

class Solution {
public:
    int minDistance(string word1, string word2) {
        // 编辑距离是一类问题
        vector<vector<int>> dp(word1.size()+1, vector<int>(word2.size()+1, 0));
        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++) {
                // dp[i][j] 表示以下标i-1为结尾的字符串word1,
                // 和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][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], dp[i-1][j]}) + 1;
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
};
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值