代码随想录算法训练营29期|day59 任务以及具体安排

第九章 动态规划part16

  •  583. 两个字符串的删除操作 
    // dp数组中存储word1和word2最长相同子序列的长度
    class Solution {public int minDistance(String word1, String word2) {int len1 = word1.length();int len2 = word2.length();int[][] dp = new int[len1 + 1][len2 + 1];for (int i = 1; i <= len1; i++) {for (int j = 1; j <= len2; j++) {if (word1.charAt(i - 1) == word2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);}}}return len1 + len2 - dp[len1][len2] * 2;}
    }// dp数组中存储需要删除的字符个数
    class Solution {public int minDistance(String word1, String word2) {int[][] dp = new int[word1.length() + 1][word2.length() + 1];for (int i = 0; i < word1.length() + 1; i++) dp[i][0] = i;for (int j = 0; j < word2.length() + 1; j++) dp[0][j] = j;for (int i = 1; i < word1.length() + 1; i++) {for (int j = 1; j < word2.length() + 1; j++) {if (word1.charAt(i - 1) == word2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1];}else{dp[i][j] = Math.min(dp[i - 1][j - 1] + 2,Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1));}}}return dp[word1.length()][word2.length()];}
    }

    思路:dp数组表示需要删除的字符的最小个数,递推公式如果word1[i-1]和word2[j-1]相等的话,直接将dp[i-1][j-1]赋值给dp[i][j],如果不相等的话,就比较取最小值。还有一个关键的地方在于初始化dp数组,当i=0时表示word1为null需要将word2里面的字符全部删掉。j=0时同理。

  •  72. 编辑距离 
    public int minDistance(String word1, String word2) {int m = word1.length();int n = word2.length();int[][] dp = new int[m + 1][n + 1];// 初始化for (int i = 1; i <= m; i++) {dp[i][0] =  i;}for (int j = 1; j <= n; j++) {dp[0][j] = j;}for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {// 因为dp数组有效位从1开始// 所以当前遍历到的字符串的位置为i-1 | j-1if (word1.charAt(i - 1) == word2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1];} else {dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i][j - 1]), dp[i - 1][j]) + 1;}}}return dp[m][n];
    }

    思路:关键就是推导递推公式,dp数组表示i-1变为j-1所需的最小操作数。

    2. 确定递推公式

    在确定递推公式的时候,首先要考虑清楚编辑的几种操作,整理如下:

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

    也就是如上4种情况。

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

    此时可能有同学有点不明白,为啥要即dp[i][j] = dp[i - 1][j - 1]呢?

    那么就在回顾上面讲过的dp[i][j]的定义,word1[i - 1] 与 word2[j - 1]相等了,那么就不用编辑了,以下标i-2为结尾的字符串word1和以下标j-2为结尾的字符串word2的最近编辑距离dp[i - 1][j - 1]就是 dp[i][j]了。

    在下面的讲解中,如果哪里看不懂,就回想一下dp[i][j]的定义,就明白了。

    在整个动规的过程中,最为关键就是正确理解dp[i][j]的定义!

    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;

    这里有同学发现了,怎么都是删除元素,添加元素去哪了。

    word2添加一个元素,相当于word1删除一个元素,例如 word1 = "ad" ,word2 = "a"word1删除元素'd' 和 word2添加一个元素'd',变成word1="a", word2="ad", 最终的操作数是一样! dp数组如下图所示意的:

                a                         a     d+-----+-----+             +-----+-----+-----+|  0  |  1  |             |  0  |  1  |  2  |+-----+-----+   ===>      +-----+-----+-----+a |  1  |  0  |           a |  1  |  0  |  1  |+-----+-----+             +-----+-----+-----+d |  2  |  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;

    综上,当 if (word1[i - 1] != word2[j - 1]) 时取最小的,即:dp[i][j] = min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1;

    递归公式代码如下:

    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;
    }
  •  编辑距离总结篇   

    动态规划之编辑距离总结篇

    本周我们讲了动态规划之终极绝杀:编辑距离,为什么叫做终极绝杀呢?

    细心的录友应该知道,我们在前三篇动态规划的文章就一直为 编辑距离 这道题目做铺垫。

    #判断子序列

    动态规划:392.判断子序列 (opens new window)给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

    这道题目 其实是可以用双指针或者贪心的的,但是我在开篇的时候就说了这是编辑距离的入门题目,因为从题意中我们也可以发现,只需要计算删除的情况,不用考虑增加和替换的情况。

  • if (s[i - 1] == t[j - 1])
    • t中找到了一个字符在s中也出现了
  • if (s[i - 1] != t[j - 1])
    • 相当于t要删除元素,继续匹配
  • 状态转移方程:

    if (s[i - 1] == t[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
    else dp[i][j] = dp[i][j - 1];
    

    #不同的子序列

    动态规划:115.不同的子序列 (opens new window)给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。

    本题虽然也只有删除操作,不用考虑替换增加之类的,但相对于动态规划:392.判断子序列 (opens new window)就有难度了,这道题目双指针法可就做不了。

    当s[i - 1] 与 t[j - 1]相等时,dp[i][j]可以有两部分组成。

    一部分是用s[i - 1]来匹配,那么个数为dp[i - 1][j - 1]。

    一部分是不用s[i - 1]来匹配,个数为dp[i - 1][j]。

    这里可能有同学不明白了,为什么还要考虑 不用s[i - 1]来匹配,都相同了指定要匹配啊。

    例如: s:bagg 和 t:bag ,s[3] 和 t[2]是相同的,但是字符串s也可以不用s[3]来匹配,即用s[0]s[1]s[2]组成的bag。

    当然也可以用s[3]来匹配,即:s[0]s[1]s[3]组成的bag。

    所以当s[i - 1] 与 t[j - 1]相等时,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];

    当s[i - 1] 与 t[j - 1]不相等时,dp[i][j]只有一部分组成,不用s[i - 1]来匹配,即:dp[i - 1][j]

    所以递推公式为:dp[i][j] = dp[i - 1][j];

    状态转移方程:

    if (s[i - 1] == t[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
    } else {dp[i][j] = dp[i - 1][j];
    }
    

    #两个字符串的删除操作

    动态规划:583.两个字符串的删除操作 (opens new window)给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最少步数,每步可以删除任意一个字符串中的一个字符。

    本题和动态规划:115.不同的子序列 (opens new window)相比,其实就是两个字符串可以都可以删除了,情况虽说复杂一些,但整体思路是不变的。

  • 当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});

    状态转移方程:

    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] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});
    }
    

    #编辑距离

    动态规划:72.编辑距离 (opens new window)给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。

    编辑距离终于来了,有了前面三道题目的铺垫,应该有思路了,本题是两个字符串可以增删改,比 动态规划:判断子序列 (opens new window),动态规划:不同的子序列 (opens new window),动态规划:两个字符串的删除操作 (opens new window)都要复杂的多。

    在确定递推公式的时候,首先要考虑清楚编辑的几种操作,整理如下:

  • 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];

    此时可能有同学有点不明白,为啥要即dp[i][j] = dp[i - 1][j - 1]呢?

    那么就在回顾上面讲过的dp[i][j]的定义,word1[i - 1] 与 word2[j - 1]相等了,那么就不用编辑了,以下标i-2为结尾的字符串word1和以下标j-2为结尾的字符串word2的最近编辑距离dp[i - 1][j - 1] 就是 dp[i][j]了。

    在下面的讲解中,如果哪里看不懂,就回想一下dp[i][j]的定义,就明白了。

    在整个动规的过程中,最为关键就是正确理解dp[i][j]的定义!

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

    操作一:word1增加一个元素,使其word1[i - 1]与word2[j - 1]相同,那么就是以下标i-2为结尾的word1 与 i-1为结尾的word2的最近编辑距离 加上一个增加元素的操作。

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

    操作二:word2添加一个元素,使其word1[i - 1]与word2[j - 1]相同,那么就是以下标i-1为结尾的word1 与 j-2为结尾的word2的最近编辑距离 加上一个增加元素的操作。

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

    这里有同学发现了,怎么都是添加元素,删除元素去哪了。

    word2添加一个元素,相当于word1删除一个元素,例如 word1 = "ad" ,word2 = "a",word2添加一个元素d,也就是相当于word1删除一个元素d,操作数是一样!

    操作三:替换元素,word1替换word1[i - 1],使其与word2[j - 1]相同,此时不用增加元素,那么以下标i-2为结尾的word1 与 j-2为结尾的word2的最近编辑距离 加上一个替换元素的操作。

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

    综上,当 if (word1[i - 1] != word2[j - 1]) 时取最小的,即:dp[i][j] = min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1;

    递归公式代码如下:

    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;
    }
    

    #总结

    心思的录友应该会发现我用了三道题做铺垫,才最后引出了动态规划:72.编辑距离 (opens new window),Carl的良苦用心呀,你们体会到了嘛!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/697602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Gartner信息图:2024 年44种安全和风险管理技术采用路线图

Gartner发布的该信息图确定了全球企业正在采用的 44 种安全相关技术&#xff0c;并根据采用阶段、部署风险和企业价值对它们进行了映射。安全和风险管理领导者可以使用此信息图将他们的技术投资与同行进行比较。 2024 年安全和风险管理技术采用路线图 SRM 领导者可以使用此信息…

RV新闻概要 --- 2024/02/23

来源&#xff1a;https://mp.weixin.qq.com/s/EEJVLQnXvgQTbtU_yrW9lw 晶心科技是一家上市公司&#xff08;TWSE&#xff1a;6533&#xff1b;SIN&#xff1a;US03420C2089&#xff1b;ISIN&#xff1a;US03420C1099&#xff09;&#xff0c;已有18 年的经营历史&#xff0c;是…

Istio实战:Istio Kiali部署与验证

目录 前言一、Istio安装小插曲 注意事项 二、Kiali安装三、Istio测试参考资料 前言 前几天我就开始捣腾Istio。前几天在执行istioctl install --set profiledemo -y 的时候老是在第二步就报错了&#xff0c;开始我用的istio版本是1.6.8。 后面查看k8s与istio的版本对应关系后发…

vCenter、vSphere Client硬盘扩容详解

文章目录 1、需求2、vSphere 操作流程3、服务器操作3.1、查看分区空间大小3.2、列出所有可用块设备的信息3.3、新建分区3.4、重读分区表信息3.5、格式化分区信息3.6、查看卷组的详细状态3.7、创建物理卷3.8、扩容卷组3.9、逻辑卷在线扩容3.10、显示物理卷属性3.11、XFS 文件系统…

如何做bug分析 ?bug分析什么 ? 为什么要做bug分析 ?

每当我们完成一个版本测试时&#xff0c;总会在测试报告中添加一些分析bug的指标 &#xff0c;主要用于分析在测试过程中存在的问题 。但是在分析的过程中你就可能遇到如下的问题 &#xff1a; 我应该分析那些指标呢 &#xff1f;每一个具体的指标该如何分析 &#xff1f;它能说…

算法——模拟

1. 什么是模拟算法&#xff1f; 官方一点来说 模拟算法&#xff08;Simulation Algorithm&#xff09;是一种通过模拟现实或抽象系统的运行过程来研究、分析或解决问题的方法。它通常涉及创建一个模型&#xff0c;模拟系统中的各种事件和过程&#xff0c;以便观察系统的行为&a…

dell戴尔电脑灵越系列Inspiron 15 3520原厂Win11系统中文版/英文版

Dell戴尔笔记本灵越3520原装出厂Windows11系统包&#xff0c;恢复出厂开箱预装OEM系统 链接&#xff1a;https://pan.baidu.com/s/1mMOAnvXz5NCDO_KImHR5gQ?pwd3nvw 提取码&#xff1a;3nvw 原厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、Office办公软件、MyD…

Jmeter接口测试 ,这应该是全网最详细的教程了

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、Jmeter 的使用步骤 打开Jmeter 安装包&#xff0c;进入\bi…

postman-使用Postman的模拟服务来模拟(mock)后端数据,完成前端模拟API调用

最近项目上比较忙&#xff0c;任务多时间紧&#xff0c;导致后端开发任务繁多&#xff0c;无法及时开发完毕&#xff0c;但是前端同学已经把对应功能开发完成&#xff0c;需要进行前后端联调来验证API及一些交互问题&#xff1b;这不能因为后端的进度来影响前端的工作完成情况&…

【Linux进程】冯·诺依曼体系结构以及操作系统的深入理解

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1.冯诺依曼体系结构特…

kafka和ZK的关系

zk相当于是kafka的一个基础设施 Kafka是一种高吞吐量、可扩展的分布式发布订阅消息系统&#xff0c;ZooKeeper是一个分布式协调服务&#xff0c;用于管理和协调分布式系统中的各种资源 Zookeeper&#xff1a;管理broker&#xff0c;consumer 创建broker后&#xff0c;向zk注册…

适用于生物行业的样本管理系统

在生物样本管理系统的应用中&#xff0c;我们首先需要了解生物样本的特点和要求。生物样本具有多样性和易变性&#xff0c;需要被妥善保存和跟踪&#xff0c;以确保其质量和可用性。 因此&#xff0c;一个有效的生物样本管理系统需要具备以下特点&#xff1a; 全面性&#xff1…

融中穿刺路径角度评估的C++技术实现

消融模型的三维渲染 我们以肝部为例&#xff0c;通常肝部在做消融手术规划时有几个步骤。 一三维重建&#xff1a; 对器官进行图像分割&#xff1b; 对肿瘤的原发区域GTV进行勾画。 二穿刺路径的规划&#xff1a; 路径规划当中有几个约束&#xff1a;穿刺深度、危及器官的…

Leetcode3036. 匹配模式数组的子数组数目 II

Every day a Leetcode 题目来源&#xff1a;3036. 匹配模式数组的子数组数目 II 解法1&#xff1a;KMP 设数组 nums 的长度为 m&#xff0c;数组 pattern 的长度为 n。 遍历数组 nums 的每个长度是 n1 的子数组并计算子数组的模式&#xff0c;然后与数组 pattern 比较&…

win系统下安装mysql5.7并配置环境变量、设置root用户和服务启动的详细操作教程

本篇文章主要讲解&#xff1a;win系统下安装mysql5.7并配置环境变量、设置root用户和服务启动的详细操作教程 日期&#xff1a;2024年2月22日 作者&#xff1a;任聪聪 一、mysql5.7版本的下载 官方下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 步骤…

【鸿蒙 HarmonyOS 4.0】状态管理

一、介绍 资料来自官网&#xff1a;文档中心 在声明式UI编程框架中&#xff0c;UI是程序状态的运行结果&#xff0c;用户构建了一个UI模型&#xff0c;其中应用的运行时的状态是参数。当参数改变时&#xff0c;UI作为返回结果&#xff0c;也将进行对应的改变。这些运行时的状…

Stable Diffusion 模型的概念、类型、下载、安装、使用

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 大家好&#xff0c;我是水滴~~ 我们在《Stable Diffusion WebUI 界面介绍》 时&#xff0c;第一个就讲到了 Stable Diffusion 模型&#xff0c;那么这个模型是什么&#xff1f;该从哪儿下载&…

多输入分类|GWO-CNN-LSTM|灰狼算法优化的卷积-长短期神经网络分类预测(Matlab)

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 灰狼优化算法&#xff1a; 卷积神经网络-长短期记忆网络&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容…

【EI会议征稿通知】第五届人工智能与机电自动化国际学术会议(AIEA 2024)

第五届人工智能与机电自动化国际学术会议&#xff08;AIEA 2024&#xff09; 2024 5th International Conference on Artificial Intelligence and Electromechanical Automation 优秀评选已启动&#xff0c;设置优秀论文、优秀报告及优秀海报多个奖项&#xff0c;丰厚奖金等…

【Java程序设计】【C00280】基于Springboot的校友社交系统(有论文)

基于Springboot的校友社交系统&#xff08;有论文&#xff09; 项目简介项目简介项目获取开发环境项目技术运行截图 项目简介 项目简介 这是一个基于Springboot的校友社交系统 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;在系统首页…