力扣● 583. 两个字符串的删除操作 ● 72. 编辑距离 ● 编辑距离总结篇

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

注意审题:

给定两个单词 word1 和 word2 ,返回使得 word1 和  word2 相同所需的最小步数

每步 可以删除任意一个字符串中的一个字符。

删除最少的字符使两者相同,说明留下来的就是最大公共子序列。不要求连续,所以可以使用● 1143.最长公共子序列 来做,最长公共子序列之外的字母都要删除,所以返回 (n1+n2-2*dp[n1][n2]) 即可。

这是间接求法,直接求:

1.dp数组含义。

dp[i][j]:以word1[i-1]为结尾的字符串,和以word2[j-1]位结尾的字符串,想要达到相等,所需要删除元素的最少次数为dp[i][j]。

2.递推公式。

如果相等:删除次数要最少,那么相等的话就不能删除,得留着,所以dp[i][j]=dp[i-1][j-1];

如果不等:2个字符串没有谁长谁短的前提,所以应该有3种情况。

①可能删掉word1[i-1],那么dp[i][j]代表的子序列和dp[i-1][j]代表的子序列删除的字母,就多了一个:word1[i-1],所以dp[i][j]=dp[i-1][j]+1;

②可能删掉word2[j-1],同样,dp[i][j]=dp[i][j-1]+1;

③都删除。都删除的话,dp[i][j]代表的子序列和dp[i-1][j-1]代表的子序列删除的字母,就多了2个:word1[i-1]和word2[j-1],所以是dp[i][j]=dp[i-1][j-1]+2;这其实也是满足情况①和情况②的,删掉2个,和dp[i-1][j]相比多删了一个word2[j-1],和dp[i][j-1]相比多删了一个word1[i-1]。所以情况①/情况②就把③包含了。所以只取①和②的最小删除数量,即Min值就是对的。

dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1);

3.初始化。

dp[i][0]。i>0时,word1[i-1]:非空串;word2[0,-1]:空串。所以应该删除word1的前i个达到相等。

dp[0][j]。同样应该删除word2的前j个达到相等。

dp[0][0]。不用删除,=0。

4.遍历顺序。

5.打印。

代码如下:

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


● 72. 编辑距离

1.dp数组含义。

dp[i][j]:数组1[0,i-1]中操作(插删换)dp[i][j]次,得到的序列是数组2[0,j-1]。注意这个操作过程是可逆的,2[0,j-1]中操作(删插换)dp[i][j]次,得到的序列是1[0,i-1]。

所以每一步操作,既可以对数组1操作,也可以对数组2操作。我觉得变换一下题目解法也没有变:请返回操作后使word1和word2相同的最大操作数。

举例:“horse”变成“ros”:

horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')

因为,对数组1 的 插入 等同于对数组2 的删除,删除同理,那么:

ros -> rose (插入 'e');horse-> rorse(将 'h' 替换为 'r');rose -> rorse(插入 'r')。

即中间每步可以选择对1操作,也可以对2操作。可见操作后可以得到很多种相同字符串(horse、rorse、rose或ros),但是过程中数组1和数组2操作的次数之和是固定的,即编辑距离是固定的。

2.递推公式。

(1)不相等的话,这3个操作都有可能发生,那么是肯定要加上1(做一个操作)。

①替换:

可以1[i-1]替换成2[j-1],也可以2[j-1]替换成1[i-1]。改了之后,得到的2个子数组最后元素相同,所以应该是在dp[i-1][j-1]的基础上替换了1或2的一个元素,所以+1。

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

②可以删除:

删除1[i-1]达到相同,说明[0,i-2]中操作之后,就能得到2[0,j-1]了,所以是在这个基础(dp[i-1][j])之上加一个删除操作即可,即dp[i][j]=dp[i-1][j]+1。

也可以删除2[j-1]达到相同,那么同理,dp[i][j]=dp[i][j-1]+1。

③可以插入:

插入1[i-1]达到相同,代表着删除2[i-1]达到相同,上面说了只是操作不同但次数相同,所以在1或2插入的情况都可以用删除表示,所以1[i-1]后面插入的情况下dp[i][j]==dp[i][j-1]+1。2[j-1]后面插入的情况下dp[i][j]=dp[i-1][j]+1。上面都包含了。

所以:dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1;

(2)相等:和上题同样是求最少操作数,所以相等的话不操作,即dp[i][j]=dp[i-1][j-1]。

3.初始化。

回忆dp的含义:

dp[i][0]=i。以下标i-1为结尾的字符串word1,和空字符串word2,最近编辑距离为dp[i][0]。

dp[0][j]=j。同理。

4.遍历顺序。

从上到下,从左到右。

5.打印。

代码如下:

class Solution {
public:int minDistance(string word1, string word2) {int n1=word1.size();int n2=word2.size();vector<vector<int>> dp(n1+1,vector<int>(n2+1,0));for(int j=0;j<=n2;++j)dp[0][j]=j;//删除for(int i=0;i<=n1;++i)dp[i][0]=i;//插入for(int i=1;i<=n1;++i){for(int j=1;j<=n2;++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],min(dp[i-1][j],dp[i][j-1]))+1;//,}}}return dp[n1][n2];}
};


● 编辑距离总结篇   

做多了总结一下:都是在dp[i-1][j-1]、dp[i-1][j]、dp[i][j-1]的基础上得到dp[i][j],要得到这个递推公式,就是得清楚,什么情况下,对A[i-1](B[j-1])做什么操作,比如上面● 72. 编辑距离,不相同的话,可能对A[i-1]和B[j-1]这一对,修改其中一个就行,所以是在dp[i-1][j-1]基础上+1……

总结一下3个编辑距离前导题:

判断子序列

判断s是不是t的子序列。根据最长公共子序列来做,dp[i][j]不要求si-1、t[j-1]结尾。

2个元素相等的时候。dp[i][j]=dp[i-1][j-1]+1;

不相等。因为序列1一定比序列2短,不相等的话dp[i][j-1]一定大于dp[i-1][j],所以dp[i][j]=dp[i][j-1];

不同的子序列

统计序列s在序列t中出现的个数。

2个元素相同。s[i-1]有可能匹配t[j-1]以及t[j-1]之前的与之相等的元素。

所以dp[i][j]=dp[i-1][j-1]+dp[i-1][j-1];

不相同。s[i-1]只可能匹配t[j-1]之前的,所以dp[i][j]=dp[i-1][j]。

两个字符串的删除操作

统计序列s和序列t,删除最少几个元素变成一样。

相同。dp[i][j]=dp[i-1][j-1]

不同。省略了删除2个dp[i-1][j-1]+2。dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1);

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

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

相关文章

探索大数据时代的决策利器:如何有效应对海量数据?

随着信息技术的快速发展,大数据时代已经到来,海量数据成为了我们生活和工作中不可忽视的一部分。这些数据来自各个方面:社交媒体、传感器、网络交易、移动设备等,每天都在以惊人的速度增长。但是,面对如此庞大的数据量,我们该如何有效地应对呢?本文将探索大数据时代的决…

13 秒插入 30 万条数据,这才是 Java 批量插入正确的姿势!

本文主要讲述通过MyBatis、JDBC等做大数据量数据插入的案例和结果。 30万条数据插入插入数据库验证 实体类、mapper和配置文件定义 User实体 mapper接口 mapper.xml文件 jdbc.properties sqlMapConfig.xml 不分批次直接梭哈 循环逐条插入 MyBatis实现插入30万条数据 J…

代码资源集合

代码资源 通信QPSKOQPSKMSK信道编码GMSK 雷达LFM及干扰技术LFM射频噪声干扰噪声调幅干扰噪声调频干扰噪声调相干扰固定移频干扰间歇采样干扰 SAR成像RD算法CS算法wk算法 SAR干扰技术射频噪声干扰调幅噪声干扰调频噪声干扰调相噪声干扰噪声卷积干扰乘积干扰移频干扰 DOA估计功率…

Linux:vim详解及使用

一、什么是vim vim的三种模式(其实有好多模式&#xff0c;目前掌握这3种即可),分别是命令模式&#xff08;command mode&#xff09;、插 入模式&#xff08;Insert mode&#xff09;和底行模式&#xff08;last line mode&#xff09;&#xff0c;各模式的功能区分如下&#…

电学基础知识

目录 电流 前言 电流的产生 电流的单位安培&#xff08;A&#xff09; 电路和电池 开路和闭路 电灯泡原理 对电池容量的理解 毫安时 毫瓦时 直流电和交流电 AC交流电 DC直流电 直流电和交流电对比 电压 对电器的电压和电流的理解 电阻 电压电阻电子的关系 欧…

python--剑指offer--中等--07. 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 例如&#xff0c;给出 前序遍历 preorder [3,9,20,15,7] 中序遍历 inorder [9,3,15,20,7] 返回如下的二叉树&#xff1a; 3/ 9 20 / 15 7 …

手把手带你入门学习TensorFlow

1. TensorFlow的来源及原理 TensorFlow是由Google Brain团队开发的开源深度学习框架&#xff0c;于2015年首次发布。它是一个功能强大、灵活且易于使用的工具&#xff0c;被广泛应用于机器学习和深度学习领域。TensorFlow的设计理念是通过构建计算图来表示复杂的数学运算和神经…

47.全排列II

// 定义一个Solution类&#xff0c;用于解决给定不重复整数数组的全排列问题 class Solution {// 初始化结果集&#xff0c;用于存放所有不重复的全排列组合List<List<Integer>> result new ArrayList<>();// 初始化路径变量&#xff0c;用于暂存当前递归生…

Vulnhub靶机:Kioptrix_Level1.3

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;192.168.56.101&#xff09; 靶机&#xff1a;Kioptrix_Level1.3&#xff08;192.168.56.109&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vul…

Springboot自动校验@NotBlank@NotNull@NotEmpty

1、依赖问题&#xff1a; 查看搭建的SpringBoot项目中 NotEmpty 是否可以引用&#xff0c;查询资料发现从SpringBoot 2.3.0之后放弃了默认对javax.validation 的支持。 <dependency> <groupId>org.springframework.boot</groupId> …

2024.3.18

1、试编程 封装一个动物的基类&#xff0c;类中有私有成员:姓名&#xff0c;颜色&#xff0c;指针成员年纪再封装一个狗这样类&#xff0c;共有继承于动物类&#xff0c;自己拓展的私有成员有:指针成员:腿的个数(整型intcount)&#xff0c;共有成员函数:会叫:void speak() 要求…

yocto系列之针对tarball编写recipes

回顾 针对借助yocto构建linux 镜像我们已经讲述了6部分&#xff0c; 简单回顾如下&#xff1a; Yocto: 第1部分 - yocto系列之yocto是个什么东东 https://mp.csdn.net/mp_blog/creation/editor/136742286 Yocto: 第2部分 - yocto系列之配置ubuntu主机 https://mp.csdn.net…

PHP修改默认上传文件缓存位置

php默认保存文件上传缓存的位置是 /tmp 版本小于php5.5 修改php.ini中**upload_tmp_dir ** upload_tmp_dir "/tmp/file" 版本大于和等于php5.5 修改php.ini中**sys_temp_dir ** sys_temp_dir "/tmp/file"谢谢大家观看&#xff0c;我们下次见

管理类联考–复试–英文面试–问题--规划介绍原因做法--汇总

文章目录 规划介绍原因做法 规划 一、提问方式&#xff1a;问题1&#xff1a;读研的规划&#xff1b;问题2&#xff1a;未来五年的规划&#xff1b;问题3&#xff1a;是否计划读博 常见问法1&#xff1a;Can you talk about your plans in the postgraduate period&#xff1f…

弗洛伊德-华沙算法求任意两点之间的最短路径算法

对于弗洛伊德-华沙算法首先是要假设研究的图中是不包含有负边的&#xff0c;对于所给的图中的任意亮点v1&#xff0c;vm&#xff0c;假设两点之间存在一条连通路径&#xff0c;对于该路径中去掉头和尾节点&#xff0c;也就是v1&#xff0c;vm&#xff0c;剩下的节点也就称之为这…

JNDI注入原理及利用IDEA漏洞复现

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

王道c语言-100元有几种换法

Description 一张面值100元的人民币换成10元、5元、2元和1元面值的票子。要求换正好40张&#xff0c;且每种票子至少一张。问&#xff1a;有几种换法&#xff1f; #include <stdio.h> int main() {int count 0;int i, j, t, k, ret 0;for (i 1; i < 37; i) {for …

自定义全能搜索HTML源码

基础功能 可自定义通过筛选搜索&#xff0c;内容结果以嵌入方式展示&#xff0c;并不会直接跳转该地址显示&#xff0c;将以内嵌页面形式浏览&#xff0c;可自行添加其他地址搜索&#xff01;也可以做搜索引导页等等&#xff01; 界面布局&#xff1b; 源码为自适应端&#…

web蓝桥杯真题:时间管理大师

代码及注释&#xff1a; <div id"box"> <div class"head"><h2>Todos</h2><p>罗列日常计划&#xff0c;做一个时间管理大师&#xff01;</p><div class"input"><span>内容</span><inp…

【C语言】病人信息管理系统

本设计实现了一个病人信息管理系统,通过链表数据结构来存储和操作病人的信息。用户可以通过菜单选择录入病人信息、查找病人信息、修改病人信息、删除病人信息、查看所有病人信息和查看专家信息等操作,还可以根据病人的科室、姓名、性别和联系方式进行查找,以及支持修改病人…