代码随想录算法训练营DAY52|C++动态规划Part13|392.判断子序列、115.不同的子序列

文章目录

  • 392.判断子序列
    • 思路
    • CPP代码
  • 115.不同的子序列
    • 思路
    • CPP代码

392.判断子序列

力扣题目链接

文章链接:392.判断子序列

视频链接:动态规划,用相似思路解决复杂问题 | LeetCode:392.判断子序列

状态:本题是编辑距离类题目的基础题,非常重要

对于给定的字符串st,我们需要判断字符串s是不是字符串t的子序列,而且并不要求st中为连续。其实我们也可以理解成,字符串t匹配s,如果遇到不相同的元素,字符串t就删除元素,如果t能和s完全相同,那么就返回true

其实本题可以使用双指针来解题,时间复杂度也是O(n),后续会给出答案。

那么为什么本题能够使用动态规划的方法呢?对于子序列问题就有最优子结构的性质。最优子结构意味着原问题的最优解可以由子问题的最优解推导出来。

思路

  • dp数组下标以及含义

老一样:

dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j]

这里设置成相同子序列长度,为了保证最后i能够全部匹配上j。如果s的长度为3,那么就必须保证对于某个j而言dp[3][j]为3

这里为什么要定义成下标i-1为结尾和以下标j-1为结尾呢?因为如果以i、j结尾,会让初始化的写法非常麻烦。

  • 确定递推公式

递推公式主要有两种操作:

  1. if (s[i - 1] == t[j - 1])

    • t中找到了一个字符在s中也出现了。找到了一个相同的字符,相同子序列长度自然要在dp[i-1][j-1]的基础上加1
  2. if (s[i - 1] != t[j - 1])

    • 相当于t要删除元素,继续匹配。t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是继承自 s[i-1]t[j-2]的比较结果了,从代码上的体现来看就是:dp[i][j] = dp[i][j - 1];
if (s[i - 1] == t[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
else dp[i][j] = dp[i][j - 1];
  • 初始化

从递推公式可以看出,我们dp[i][j]都是依赖于dp[i - 1][j - 1] dp[i][j-1],也就是说,我们的当前格子需要左上方格子和左边格子才能推导出来。

通过本图片,我们也可以看出为什么要表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j]。就是为了在二维句珍重可以留出初始化空间。

  • 确定遍历顺序

根据递推公式来的,从上到下,从左到右

  • 举例推导dp数组

以示例一为例,输入:s = “abc”, t = “ahbgdc”,dp状态转移图如下:

CPP代码

class Solution {
public:bool isSubsequence(string s, string t) {vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));for (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] + 1;else dp[i][j] = dp[i][j - 1];}}if (dp[s.size()][t.size()] == s.size()) return true;return false;}
};

115.不同的子序列

力扣题目链接

视频讲解:动态规划之子序列,为了编辑距离做铺垫 | LeetCode:115.不同的子序列

文章讲解:115.不同的子序列

KMP算法求的是连续序列,本题中仅仅是来求子序列(字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。)

思路

  • 确定dp数组下标以及含义

dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]

  • 确定递推公式

这一类问题,基本是要分析两种情况,这里是跟上一题一样的

  1. s[i - 1] 与 t[j - 1]相等

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

一种是使用s[j-1]来匹配字符串,另一种是不使用s[j - 1]来匹配字符串(因为s中可能有多个字符能与t[j - 1])匹配。

所以我们的递推公式

if (s[i - 1] == t[j - 1]){dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];//分别对应用s[j-1]匹配和不用s[j-1]匹配
}
  • 使用 s[i - 1] 来匹配 t[j - 1],此时 s 的前 i 个字符匹配 t 的前 j 个字符,可以看作是在 s 的前 i - 1 个字符匹配 t 的前 j - 1 个字符的基础上,将 s[i - 1]t[j - 1] 匹配起来。因此,此时 dp[i][j] 应该等于 dp[i - 1][j - 1]
  • 不使用 s[i - 1] 来匹配 t[j - 1],而是保持 s 的前 i - 1 个字符匹配 t 的前 j 个字符,即 s 的前 i 个字符在 t 的前 j 个字符中的匹配方式不依赖于 s[i - 1],而是与 s[i - 2] 以及 t[j - 1] 的匹配方式相关。因此,此时 dp[i][j] 应该等于 dp[i - 1][j]
  • 并且要注意的是这里的结果是相加的!
  1. s[i - 1] 与 t[j - 1] 不相等

s[i - 1]t[j - 1]不相等时,dp[i][j]只有一部分组成,不用s[i - 1]来匹配(就是模拟在s中删除这个元素),此时的状态还是依赖于s[i-1]的前一个元素即:dp[i - 1][j]

  • dp数组的初始化

还是从递推公式来的,所以我们必须初始化dp[i][0]dp[0][j]

从递推公式的定义出发,

那么dp[i][0]一定都是1,因为也就是把以i-1为结尾的s,删除所有元素,出现空字符串的个数就是1。

那么dp[0][j]一定都是0,s如论如何也变成不了t

dp[0][0]呢?那必然是1,因为空字符串s可以删除0个元素,变成空字符串t

vector<vector<long long>> dp(s.size() + 1, vector<long long>(t.size() + 1));
for (int i = 0; i <= s.size(); i++) dp[i][0] = 1;
for (int j = 1; j <= t.size(); j++) dp[0][j] = 0; 
  • 确定遍历顺序

关于遍历顺序从上图也能看出,总左到右,从上到下

  • 打印dp数组

CPP代码

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;for (int j = 1; j < t.size(); j++) dp[0][j] = 0;for (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];} else {dp[i][j] = dp[i - 1][j];}}}return dp[s.size()][t.size()];}
};

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

电气元器件中四个三

目录 三控制 PLC 驱动器 变频器 三电机 步进电机 伺服电机 三相电机 三串口 RS232 RS422 RS485 三协议 MOOBUS PROFINET CC-LINK 三控制 PLC PLC代表可编程逻辑控制器。它是一种用于工业自动化的计算机设备&#xff0c;用于控制机械和工艺。PLC用于监控传感器和…

【自动化测试】使用MeterSphere进行接口测试

一、接口介绍二、接口测试的过程三、接口自动化测试执行自动化流程 四、接口之间的协议HTTP协议 五、 接口测试用例设计接口文档 六、使用MeterSphere创建接口测试创建接口定义设计接口测试用例 一、接口介绍 自动化测试按对象分为&#xff1a;单元测试、接口测试、UI测试等。…

强大而简洁:初学Python必须掌握的14个单行代码

Python的魅力与单行代码的重要性 Python&#xff0c;作为一种高级编程语言&#xff0c;自诞生以来就以其简洁、易读、易学的特性而广受开发者喜爱。其魅力不仅在于其强大的功能和广泛的应用领域&#xff0c;更在于其能够用简洁的代码实现复杂的功能&#xff0c;这种能力在很大…

C#实战—代码实现收发文件智能化

在信息化的今天&#xff0c;收发电子文档几乎是每个朋友都要经历的事情。比如班级学委和班长需要收发作业&#xff0c;企业管理者需要收发工作文件。但是&#xff01;&#xff01;&#xff01; 每到要交结果时&#xff0c;往往会发现总会有一些人没有即使交上&#xff0c;50个…

【信息收集】子域名扫描---subdomainbrute

下载地址&#xff1a;GitHub - lijiejie/subDomainsBrute: A fast sub domain brute tool for pentesters 用字典的方式去发现url的二级、三级、四级....子域名 并会自动在文件目录下生成一个txt记录 python subDomainsBrute.py csdn.net(别加 www.)

展会进行时|百华鞋业亮相第135届中国进出口商品交易会(广交会)三期,展会现场人气爆棚!

第135届中国进出口商品交易会&#xff08;广交会&#xff09;三期如约而至&#xff0c;本届展会汇集了来自世界各地的参展企业&#xff0c;带来各行业前沿技术与新产品展出。百华鞋业携足部安防职业鞋、户外作训靴等系列新产品强势亮相展会&#xff0c;位于2.2 G25-26 H23-24的…

eNSP-DHCP服务配置

一、拓扑结构搭建 二、主机配置 pc1、pc2 三、路由器配置 <Huawei>sys #进入系统视图 [Huawei]int g0/0/0 #进图接口 [Huawei-GigabitEthernet0/0/0]ip address 192.168.0.1 24 #设置接口ip [Huawei-GigabitEthernet0/0/0]q #返回上一级 [Huawei]dhcp enable #开启DHCP服…

手撸Mybatis(四)——连接数据库进行简单查询

本专栏的源码&#xff1a;https://gitee.com/dhi-chen-xiaoyang/yang-mybatis。 添加数据库操作模板 对于JDBC操作&#xff0c;一般包括以下几个步骤&#xff1a; 1&#xff09;注册驱动 2&#xff09;建立连接 3&#xff09;执行sql语句 4&#xff09;处理结果 5&#xff09…

【Python基础】进程

文章目录 [toc]程序与进程的区别与联系同步任务示例 并行任务示例进程调度的“随机性” 进程属性与方法process_object.start()方法process_object.join()方法process_object.daemon属性没有设置守护进程的情况设置守护进程的情况 process_object.current_process()方法 进程通…

(三)Appdesigner-界面转换及数据导入和保存

提示&#xff1a;文章为系列文章&#xff0c;可以在对应学习专栏里面进行学习。对应资源已上传 目录 前言 一、Appdesigner是什么&#xff1f; 二、界面切换 三、数据导入及保存 &#xff08;一&#xff09;数据导入 &#xff08;二&#xff09;数据保存 总结 前言 Appd…

ZooKeeper数据模型你懂吗?

ZooKeeper数据节点你知道吗&#xff1f;那数据节点有什么类型&#xff1f;数据节点的版本呢&#xff1f;听说ZooKeeper还有事务ID&#xff0c;你知不知道啊&#xff1f;还有Watcher机制呢&#xff1f;ZooKeeper作为一个典型的分布式数据一致性的解决方案&#xff0c;ZooKeeper的…

【Python项目】基于DJANGO的【医院体检预约系统】

技术简介&#xff1a;使用Python技术、DJANGO框架、MYSQL数据库等实现。 系统简介&#xff1a;系统采用了在线预约和挂号的方式&#xff0c;用户可以通过网站进行预约和挂号操作。同时&#xff0c;系统还提供了医生的详细介绍和评价&#xff0c;方便用户选择医生。 研究背景&a…

Django之单文件上传(以图片为例)

一&#xff0c;创建项目 初始化&#xff0c;数据迁移&#xff0c;创建superuser&#xff0c;创建app等 二&#xff0c;配置settings.py 1&#xff0c;配置数据库&#xff08;本作者使用的mysql&#xff09;&#xff0c;以前文章有提到 2&#xff0c;配置静态文件存放路径 STAT…

关于YOLO8学习(五)安卓部署ncnn模型--视频检测

前文 关于YOLO8学习(一)环境搭建,官方检测模型部署到手机 关于YOLO8学习(二)数据集收集,处理 关于YOLO8学习(三)训练自定义的数据集 关于YOLO8学习(四)模型转换为ncnn 简介 本文将会讲解: (1)使用前文生成的ncnn模型,部署到安卓端,并且实现视频中,人脸的检测…

CSS精灵图、字体图标、HTML5新增属性、界面样式和网站 favicon 图标

精灵图 为什么要使用精灵图 一个网页中往往会应用很多小的背景图像作为修饰&#xff0c;当网页中的图像过多时&#xff0c;服务器就会频繁地接收和发送请求图片&#xff0c;造成服务器请求压力过大&#xff0c;这将大大降低页面的加载速度,因此&#xff0c;为了有效地减少服务…

农作物害虫检测数据集VOC+YOLO格式18975张97类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;18975 标注数量(xml文件个数)&#xff1a;18975 标注数量(txt文件个数)&#xff1a;18975 标…

ARL资产侦察灯塔系统安装和使用(含实用配置说明)

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、官方介绍 ARL全称&#xff1a;Asset Reconnaissance…

C#图像:1.图像区域分割与提取

&#xff08;1&#xff09;创建一个名为SplitImage的窗体的应用程序&#xff0c;将窗体改名为FormSplitImage。 &#xff08;2&#xff09;创建一个名为ImageProcessingLibrary的类库程序&#xff0c;为该工程添加名为ImageProcessing的静态类 &#xff08;3&#xff09;为Imag…

智慧校园云平台源码,SaaS运营云平台(支持多学校、多校园使用)

智慧班牌系统&#xff0c;又称电子班牌系统&#xff0c;是一种基于互联网技术的综合管理工具。通过在教室内安装显示屏&#xff0c;并连接到学校管理系统&#xff0c;实现教学资源展示、信息发布、学生管理等多种功能的集成。该系统旨在加强学校班级文化建设和班级风采展示&…

【自留】运行一个开源项目

运行一个开源项目 首先是运行起来 1. 拿到地址 拿到你想要的项目的地址 2. 克隆 打开编辑器 VSCode &#xff0c;创建一个放项目的文件夹&#xff0c;控制台输入以下代码克隆项目 git clone 克隆地址gitee克隆地址在这看&#xff1a; github上项目的话&#xff0c;在这…