首页 > 编程语言 >【算法训练营day56】LeetCode583. 两个字符串的删除工作 LeetCode72. 编辑距离

【算法训练营day56】LeetCode583. 两个字符串的删除工作 LeetCode72. 编辑距离

时间:2023-02-22 18:44:06浏览次数:84  
标签:LeetCode72 LeetCode583 编辑 word1 day56 word2 操作 递推 dp

LeetCode583. 两个字符串的删除工作

题目链接:583. 两个字符串的删除工作

独上高楼,望尽天涯路

突然感觉有那么一点开窍了,可以照猫画虎了。

class Solution {
public:
    int minDistance(string word1, string word2) {
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
        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);
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
};

慕然回首,灯火阑珊处

本题最重要的还是理解递推公式的含义。

  • 当word1[i - 1]与word2[j - 1]相同的时候
  • 当word1[i - 1]与word2[j - 1]不相同的时候

当word1[i - 1]与word2[j - 1]相同的时候,dp[i][j] = dp[i - 1][j - 1];

当word1[i - 1]与word2[j - 1]不相同的时候,有三种情况:

情况一:删word1[i - 1],最少操作次数为dp[i - 1][j] + 1

情况二:删word2[j - 1],最少操作次数为dp[i][j - 1] + 1

情况三:同时删word1[i - 1]和word2[j - 1],操作的最少次数为dp[i - 1][j - 1] + 2

那最后当然是取最小值,所以当word1[i - 1]与word2[j - 1]不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 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)

这里可能不少录友有点迷糊,从字面上理解 就是 当 同时删word1[i - 1]和word2[j - 1],dp[i][j-1]本来就不考虑word2[j - 1]了,那么我在删word1[i - 1],是不是就达到两个元素都删除的效果,即dp[i][j-1] + 1


LeetCode72. 编辑距离

题目链接:72. 编辑距离

独上高楼,望尽天涯路

困难题!直接看题解。

慕然回首,灯火阑珊处

看完后感觉没有想象中的那么难,本质上还是前几道题铺垫出来的解题思想。

  1. 确定dp数组以及下标的含义

dp[i][j]表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]

  1. 确定递推公式

递推公式中的关键操作如下所示。

if (word1[i - 1] == word2[j - 1])
    不操作
if (word1[i - 1] != word2[j - 1])
    增
    删
    换

if (word1[i - 1] == word2[j - 1])那么说明不用任何编辑,dp[i][j]就应该是dp[i - 1][j - 1],即dp[i][j] = dp[i - 1][j - 1];

if (word1[i - 1] != word2[j - 1]),此时就需要编辑了,如何编辑呢?

  • 操作一:word1删除一个元素,那么就是以下标i - 2为结尾的word1与j-1为结尾的word2的最近编辑距离 再加上一个操作。

dp[i][j] = dp[i - 1][j] + 1

  • 操作二:word2删除一个元素,那么就是以下标i - 1为结尾的word1与j-2为结尾的word2的最近编辑距离 再加上一个操作。

dp[i][j] = dp[i][j - 1] + 1

  • 操作三:替换元素,word1替换word1[i - 1],使其与word2[j - 1]相同,此时不用增删加元素。

可以回顾一下,if (word1[i - 1] == word2[j - 1])的时候我们的操作是dp[i][j] = dp[i - 1][j - 1]对吧。

那么只需要一次替换的操作,就可以让word1[i - 1]和word2[j - 1]相同。

所以dp[i][j] = dp[i - 1][j - 1] + 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++) {
                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 - 1][j], dp[i][j - 1]}) + 1;
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
};

标签:LeetCode72,LeetCode583,编辑,word1,day56,word2,操作,递推,dp
From: https://www.cnblogs.com/BarcelonaTong/p/17145476.html

相关文章

  • leetcode724. 寻找数组的中心下标(数组)
    题目描述:给你一个整数数组nums,请计算数组的中心下标。数组中心下标是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。如果中心下标位于数组最......
  • 前端Vue2-Day56
    消息订阅与发布pubsub:实现任意组件间通信使用步骤:①安装pubsub-js:npmipubsub-js②引入:importpubsubfrom'pubsub-js'③订阅消息:使用pubsub自带的subscribe方法......
  • 学习python-Day56
    今日学习内容序列化类常用字段类和字段参数常见字段类BooleanField BooleanField()NullBooleanField NullBooleanField()CharField CharField(max_length=None,m......
  • 学习python-Day56
    今日学习内容补充:JSON知识点JSON是JavaScript(JavaScriptObjectNotation)是轻量级的文本数据交换的格式,JSON解析器和JSON支持许多不同的编程语言。独立于其......