代码随想录Day 45|leetcode题目:115.不同的子序列、583. 两个字符串的删除操作、72. 编辑距离
提示:DDU,供自己复习使用。欢迎大家前来讨论~
文章目录
- 题目
- 题目一: 115.不同的子序列
- 解题思路:
- 1. 确定dp数组(dp table)以及下标的含义
- 2. 确定递推公式
- 3. dp数组如何初始化
- 4. 确定遍历顺序
- 5. 举例推导dp数组
- 代码实现
- 题目二:583. 两个字符串的删除操作
- 解题思路:
- 1. 确定dp数组(dp table)以及下标的含义
- 2. 确定递推公式
- 3. dp数组如何初始化
- 4. 确定遍历顺序
- 5. 举例推导dp数组
- 代码实现
- 动态规划二(求最长公共子序列)
- 代码实现
- 题目三:72. 编辑距离
- 解题思路
- 1. 确定dp数组(dp table)以及下标的含义
- 2. 确定递推公式
- 3. dp数组如何初始化
- 4. 确定遍历顺序
- 5. 举例推导dp数组
- 代码实现
- 编辑距离总结篇
- 编辑距离问题
动态规划Part12
题目
题目一: 115.不同的子序列
115. 不同的子序列
解题思路:
这道题目要求判断字符串s是否包含字符串t作为子序列。这里的子序列指的是,t的字符可以不连续,但顺序必须保持一致。解题思路使用动态规划,具体步骤如下:
1. 确定dp数组(dp table)以及下标的含义
定义二维数组dp[i][j],其中dp[i][j]表示以s的前i-1个字符为结尾的子序列中,出现以t的前j-1个字符为结尾的子序列的个数。
2. 确定递推公式
根据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] = dp[i - 1][j]。因为s[i - 1]不匹配t[j - 1],只能忽略s[i - 1]。
3. dp数组如何初始化
dp[i][0] = 1:任何字符串的子序列都至少包含空字符串,所以初始化为1。dp[0][j] = 0:空字符串s不能包含任何非空字符串t作为子序列,所以初始化为0。dp[0][0] = 1:空字符串是自身的子序列。
4. 确定遍历顺序
遍历顺序为从左到右,从上到下,确保每个dp[i][j]的值都是基于已经计算过的dp[i-1][j]和dp[i-1][j-1]来计算的。
5. 举例推导dp数组
以具体例子(如s = "baegg",t = "bag")来手动计算dp数组,验证递推公式的正确性。
代码实现
class Solution {
public:int numDistinct(string s, string t) {vector<vector<uint64_t>> dp(s.size() + 1, vector<uint64_t>(t.size() + 1));for (int i = 0; i <= s.size(); i++) dp[i][0] = 1; // 空字符串的子序列计数为1for (int j = 1; j <= t.size(); j++) dp[0][j] = 0; // 空s不能包含非空tfor (int i = 1; i <= s.size(); i++) {for (int j = 1; j <= t.size(); j++) {if (s[i - 1] == t[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]; // s[i-1]匹配t[j-1]或不匹配} else {dp[i][j] = dp[i - 1][j]; // s[i-1]不匹配t[j-1],忽略s[i-1]}}}return dp[s.size()][t.size()]; // 返回s的所有子序列中包含t的计数}
};
时间复杂度为O(n*m),空间复杂度也为O(n*m),其中n和m分别是字符串s和t的长度。
题目二:583. 两个字符串的删除操作
583. 两个字符串的删除操作
解题思路:
这道题目要求找出将两个字符串转换为彼此所需的最少删除次数,可以通过动态规划来解决。以下是详细的解题思路:
1. 确定dp数组(dp table)以及下标的含义
定义二维数组dp[i][j],其中dp[i][j]表示将字符串word1的前i-1个字符和字符串word2的前j-1个字符转换为彼此所需的最少删除次数。
2. 确定递推公式
根据word1[i - 1]与word2[j - 1]是否相等,分两种情况:
- 相等:
dp[i][j] = dp[i - 1][j - 1]。因为当两个字符相等时,不需要删除这两个字符。 - 不相等:
dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1)。因为当两个字符不相等时,可以选择删除word1的一个字符或者删除word2的一个字符,取两者的最小值。
3. dp数组如何初始化
dp[i][0] = i:表示word2为空字符串时,需要删除word1的前i-1个字符。dp[0][j] = j:表示word1为空字符串时,需要删除word2的前j-1个字符。
4. 确定遍历顺序
遍历顺序为从上到下,从左到右,确保每个dp[i][j]的值都是基于已经计算过的dp[i-1][j]和dp[i][j-1]来计算的。
5. 举例推导dp数组
以具体例子(如word1 = "sea",word2 = "eat")来手动计算dp数组,验证递推公式的正确性。
代码实现
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()];}
};
时间复杂度为O(n*m),空间复杂度也为O(n*m),其中n和m分别是字符串word1和word2的长度。
动态规划二(求最长公共子序列)
另一种解法是求两个字符串的最长公共子序列(LCS),然后用两个字符串的总长度减去最长公共子序列的长度的两倍,即为最少删除次数。
代码实现
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++){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()-dp[word1.size()][word2.size()]*2;}
};
时间复杂度为O(n*m),空间复杂度为O(n*m)。
题目三:72. 编辑距离
72. 编辑距离
解题思路
编辑距离问题是一个经典的动态规划问题,用于计算两个字符串之间的最小编辑操作次数,使得一个字符串可以转换成另一个字符串。以下是详细的解题思路:
1. 确定dp数组(dp table)以及下标的含义
定义二维数组dp[i][j],其中dp[i][j]表示以下标i-1为结尾的字符串word1和以下标j-1为结尾的字符串word2之间的最小编辑距离。
2. 确定递推公式
根据word1[i - 1]与word2[j - 1]是否相等,分两种情况:
- 相等:不需要任何编辑操作,即
dp[i][j] = dp[i - 1][j - 1]。 - 不相等:需要进行编辑操作,可能的操作包括:
- 删除
word1的一个字符:dp[i - 1][j] + 1 - 删除
word2的一个字符:dp[i][j - 1] + 1 - 替换
word1的一个字符:dp[i - 1][j - 1] + 1 - 选择最小操作次数:
dp[i][j] = min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1
- 删除
3. dp数组如何初始化
dp[i][0] = i:表示将word1的前i-1个字符转换为一个空字符串需要删除i次。dp[0][j] = j:表示将一个空字符串转换为word2的前j-1个字符需要添加j次。
4. 确定遍历顺序
遍历顺序为从上到下,从左到右,确保每个dp[i][j]的值都是基于已经计算过的dp[i-1][j]、dp[i][j-1]和dp[i-1][j-1]来计算的。
5. 举例推导dp数组
以具体例子(如word1 = "horse",word2 = "ros")来手动计算dp数组,验证递推公式的正确性。
代码实现
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()];}
};
时间复杂度为O(n*m),空间复杂度也为O(n*m),其中n和m分别是字符串word1和word2的长度。
编辑距离总结篇
- 判断子序列:判断一个字符串是否为另一个字符串的子序列,只涉及删除操作。
- 不同的子序列:计算一个字符串在另一个字符串子序列中出现的次数,涉及删除操作。
- 两个字符串的删除操作:计算使两个字符串相同的最少删除次数,涉及两个字符串的删除操作。
编辑距离问题
问题定义:给定两个字符串word1和word2,计算将word1转换成word2的最少操作数,操作包括插入、删除和替换。
相关文章:
代码随想录Day 45|leetcode题目:115.不同的子序列、583. 两个字符串的删除操作、72. 编辑距离
提示:DDU,供自己复习使用。欢迎大家前来讨论~ 文章目录 题目题目一: 115.不同的子序列解题思路:1. 确定dp数组(dp table)以及下标的含义2. 确定递推公式3. dp数组如何初始化4. 确定遍历顺序5. 举例推导dp数…...
浮点数在内存中的存储详解(超详细)
目录 1. 浮点数存储规则 2. IEEE754规定: 3. 关于M的说明: 4. 关于E的说明: 5. 关于S的说明: 6.浮点数从内存中取出(三种情况) 情况1:E不全为0或不全为1 情况2:E全为0 情况3&a…...
Maven下载安装
下载 下载地址:Maven – Download Apache Maven 选择合适的版本进行下载 windows&Linux安装 1, 解压apache-maven-3.6.1.rar即安装完成 2, 配置环境变量MAVEN_HOME为安装路径,并将MAVEN_HOME的bin目录配置到PATH下 3,…...
Qt:Q_GLOBAL_STATIC实现单例(附带单例使用和内存管理)
前言 本文主要写Q_GLOBAL_STATIC实现单例以及单例的释放,网上很多教程只有单例的创建,但是并没有告诉我们单例的内存管理,这就很头疼。 正文 使用 Qt 的 Q_GLOBAL_STATIC // Singleton.h #ifndef SINGLETON_H #define SINGLETON_H#includ…...
URL.createObjectURL 与 FileReader:Web 文件处理两大法宝的对比
URL.createObjectURL 与 FileReader:Web 文件处理两大法宝的对比 在Web开发中,处理用户上传的文件是一项常见且重要的任务。URL.createObjectURL和FileReader是两种常用于此目的的Web API,它们各有特点,适用于不同的场景。本文将…...
零基础考过软考信息系统项目管理师经验分享
选择适合的课程:如果你是零基础,建议找一些专门针对新手的课程,讲解通俗易懂。 刷题至关重要:软考的题库很庞大,多做题是必须的。 做好笔记和复习:上课时要做好笔记,课后及时复习,…...
机器学习课程学习周报十二
机器学习课程学习周报十二 文章目录 机器学习课程学习周报十二摘要Abstract一、机器学习部分1.1 fGAN: General Framework of GAN1.2 CycleGAN1.3 Auto-Encoder1.4 概率论复习(一) 总结 摘要 本周的学习内容涵盖了fGAN框架、CycleGAN、自编码器以及概率…...
python多线程程序设计 之二
python多线程程序设计 之二 线程同步机制lock对象acquirereleaselocked RLock对象条件变量条件变量应用实列实列代码 线程同步机制 lock对象 原语锁是一种同步原语,锁定时不属于特定线程。在Python中,它是目前可用的最低级别的同步原语,由_…...
k8s用StatefulSet部署redis
redis-config.yaml (配置文件) apiVersion: v1 kind: ConfigMap metadata:name: redis-config data:redis.conf: |# Redis general configuration bind 0.0.0.0 protected-mode no port 6379 dir /data appendonly yesse…...
flink on k8s
1.修改host文件 vi /etc/hosts 添加如下内容 这样搭集群的时候就不用记ip了 #::1 localhost localhost.localdomain localhost6 localhost6.localdomain6127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 165.154.221.97 tlb-001 k8s01 k8s-m…...
Java集合(八股)
这里写目录标题 Collection 接口List 接口ArrayList 简述 1. ArrayList 和 LinkedList 区别?⭐️⭐️⭐️⭐️2. ArrayList 和 Array 的区别?⭐️⭐️⭐️ArrayList 和 Vector 区别?⭐️⭐️ArrayList 的扩容机制?⭐️⭐️⭐️ Qu…...
python+adb
#!/usr/bin/python env # -*- coding: utf-8 -*- import os import sys import subprocess from time import sleepimport logging logging.basicConfig(levellogging.DEBUG) class ScreenCapture():def get_screen_size(self):"""获取手机分辨率""&q…...
AIGC文本生成
文本生成是一种人工智能技术,它基于深度学习算法,根据给定的提示信息创作出有逻辑、连贯的文本内容。 文本生成所需的输入(提示或Prompt)可以是简单的关键词、一句话概述或是更复杂的指令和上下文信息。文本生成模型通过分析大量…...
系统架构设计师教程 第5章 5.4 软件测试 笔记
5.4 软件测试 5.4.1 测试方法 ★★★★★ 软件测试方法的分类有很多种, 以测试过程中程序执行状态为依据可分为静态测试 (Static Testing,ST) 和动态测试 (Dynamic Testing,DT); 以具体实现算法细节和系统内部结构的相关情况为根据可分黑盒测试、白盒测试和灰盒测…...
ASPICE评估全流程解析:汽车软件开发组织能力的系统化评估
ASPICE(Automotive SPICE)评估的过程是一个系统化和详尽的流程,旨在评估汽车软件开发组织在软件开发过程方面的能力。 以下是ASPICE评估过程的详细描述: 1. 评估准备阶段 a. 确定评估目标和范围 明确评估的目标,如评…...
合并RAR分卷压缩包
因为文件压缩之后体积仍然过大,大家可能会选择进行分卷压缩,那么rar分卷压缩包之后如何合并成一个压缩包文件呢?今天我们来学习rar分卷压缩包,合并成一个的方法。 最基础的方法就是将分卷压缩包解压出来之后,再将文件…...
重生奇迹MU 想去哪就去哪玩 轻松玩转翅膀属性
在重生奇迹MU这个游戏中,玩家需要扫荡各种怪物,勇斗BOSS,与其他玩家激战。在这个充满冒险的旅程中,翅膀是最重要的装备之一。拥有一个属性强大的翅膀,代表着玩家的成长与强大。穿上它,加速你的冒险之旅吧&a…...
Lnux-gcc/g++使用
目录 1.gcc/g介绍 1.什么是 gcc / g 2.gcc/g指令格式 2. gcc / g 实现程序翻译的过程 1.预处理(进行宏替换) 2.编译(生成汇编) 3.汇编(生成机器可识别代码) 4.连接(生成可执行文件或库文件) 1.gcc/g介绍 1.什么…...
用Python创建一个键盘输入捕获程序
目录 简介 环境准备 安装依赖 项目结构 编写代码 1. 导入库 2. 定义回调函数 3. 启动键盘监听器 4. 整合代码 运行程序 结论 简介 在这篇博文中,我们将探索如何使用Python编写一个简单的键盘输入捕获程序。这个程序将实时捕获用户的键盘输入并在控制台中显示出来。…...
Mybatis中Like模糊查询三种处理方式
目录 Mybatis中Like模糊查询三种处理方式 1.通过单引号拼接${} 1)mapper接口 2)Mapper.xml 3)测试代码 4) 测试结果 2.通过concat()函数拼接(个人推荐使用这种) 1)mapper接口 2)Mapper.xml 3)测试代码 4) 测…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...
