Day56 | 583. 两个字符串的删除操作, 72. 编辑距离

Day56 | 583. 两个字符串的删除操作, 72. 编辑距离

两个字符串的删除操作

LeetCode题目:https://leetcode.cn/problems/delete-operation-for-two-strings/

  今天的两道题与昨天类似,DP数组的设定就是以i - 1结尾的word1字符串,和j - 1结尾的word2字符串相同需要的最小步数。因此同理可以进行初始化,当word1为0时候,那么Word2想要相同,就只能减去word2字符数量的字符。也就是进行j次操作。Word2为0的时候Word1也同理。因此初始化

    for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;
    for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;

  同样,每个新的状态都由三种转移的可能,当i - 1 和j - 1的字符相同时,则说明当前匹配的字符不需要删除,因此从对角状态转移,即 dp[i][j] = dp[i - 1][j - 1]; 而当不匹配的时候,因为我要求得的是最少的操作数量,因此需要从i - 2 和 j - 1 以及i - 1和 j - 2 两种情况下获取最多的一个状态继承操作数量后,再额外进行一次删除操作即可。

  代码如下:

class Solution {
public:
    int minDistance(string word1, string word2) {
        /* 以i - 1结尾的word1字符串,和j - 1结尾的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++) {
                if (word1[i - 1] == word2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                }else {
                    dp[i][j] = min(dp[i][j - 1] + 1, dp[i - 1][j] + 1);
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
};

编辑距离

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

  其实和删除操作类似,以i - 1结尾的word1字符串,和j - 1结尾的word2字符串相同需要的最小操作数。

  之后进行递推,因为还是二维,所以递推的方式和之前相同,只有考虑情况不同。当i - 1 和 j - 1位置字符相等时,该位置不用操作,相当于i - 2结尾的s子序列在j - 2中出现过的操作数就是现在i - 1和 j - 1序列出现的个数。

  当不相同的时候,则存在三种操作的可能,替换操作:将i - 1新增的字符进行一次操作,更换为 j - 1更新的字符串。删除/添加:当i - 2字符串和j - 1字符串存在操作数,在额外增加一个新字符后,可以直接将新增的i - 1字符删除。当i - 1和 j - 2时候同理。因此需要对比三种操作的最小值。

  代码如下:

class Solution {
public:
    int minDistance(string word1, string word2) {
        /* 将下标到i-1的word1字符串,转换成下标到j-1的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++) {
                if (word1[i - 1] == word2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                }else {
                    dp[i][j] = min(min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + 1);
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值