代码随想录刷题笔记 Day 58 | 判断子序列 No.392 | 不同的子序列 No.115

文章目录

    • Day 58
      • 01. 判断子序列(No. 392)
        • <1> 题目
        • <2> 题解
        • <3> 代码
      • 02. 不同的子序列(No. 115)
        • <1> 题目
        • <2> 题解
        • <3> 代码

Day 58

01. 判断子序列(No. 392)

题目链接

代码随想录题解

<1> 题目

给定字符串 st ,判断 s 是否为 t 的子序列。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace""abcde"的一个子序列,而"aec"不是)。

进阶:如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

致谢:特别感谢 @pbrother 添加此问题并且创建所有测试用例。

示例 1:

输入:s = “abc”, t = “ahbgdc”
输出:true

示例 2:

输入:s = “axc”, t = “ahbgdc”
输出:false

提示:

  • 0 <= s.length <= 100
  • 0 <= t.length <= 10^4
  • 两个字符串都只由小写字符组成。
<2> 题解

如果仅考虑动态规划解法的话,本题是昨天的 最长公共子序列 的简化版本。

子序列的定义为:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

**s 是否是 t 的公共子序列,其实也就代表了 t 和 s 的最长公共子序列是否是 s。**所以本题的动态规划解法就是求得它们两个最长公共子序列的长度,然后判断长度是否等于 s 的长度即可;剩下的步骤和求最长公共子序列的方法就完全相同了。

1. 状态

既然是求最长的公共子序列,那就涉及到 长度,可以分解成如下的子问题:

s 的前一个元素和 t 第一个元素组成的最长公共子序列是多少?

s 的前两个元素和 t 第一个元素组成的最长公共子序列是多少?

s 的前三个元素和 t 第一个元素组成的最长公共子序列是多少?

。。。。。。

一直推到到 s 的前 s.length() 个元素和 t 的前 t.length() 个元素的最长公共子序列的长度为多少。

那这个状态能否转移呢?s 的前 m 个元素和 t 的前 n 个元素的公共子序列的长度,是可以通过 m - 1 和 n - 1 组成的公共子序列的长度推出的。

2. dp 数组的含义

dp 数组设定为一个二维数组 dp[i][j] 表示 s 的钱 i - 1 个元素和 t 的前 j - 1 个元素构成的最长公共子序列的大小。

使用这种后移一位的方式可以减少初始化的复杂程度。

3. 递推公式

对于 s 的第 i 个元素和 t 的第 j 个元素有两种情况:

  • 它们是相等的,所以它们可以作为构成子序列的元素存在
  • 它们不相等,在这个 长度范围 内需要被剔除

如果它们相等,那

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

如果它们不相等,那就是延续前面的子序列在如下三个中取最大:

  • dp[i - 1][j]
  • dp[i - 1][j - 1]
  • dp[i][j - 1]

但因为第二种情况被包含了,所以仅对前两个情况取值即可,也就是

dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);

4. 初始化

本题中,下层的推导依赖的是左上角的值,所以只需要初始化第一行和第一列即可。

而本题的第一行代表 s 的第 0 个元素(从 1 开始,0 没有意义)和 t 的最长公共子序列,为 0

第一列代表着 t 的第 0 个元素和 s 的最长公共子序列,也是 0

所以均初始化为 0 即可,也就是不需要初始化。

<3> 代码
class Solution {public boolean isSubsequence(String s, String t) {int m = 0;int n = 0;while (m < s.length() && n < t.length()) {if (s.charAt(m) == t.charAt(n)) {m++;n++;} else {n++;}}return m == s.length();}
}

02. 不同的子序列(No. 115)

题目链接

代码随想录题解

<1> 题目

给你两个字符串 st ,统计并返回在 s子序列t 出现的个数,结果需要对 109 + 7 取模。

示例 1:

输入:s = “rabbbit”, t = “rabbit”
输出:3
解释:
如下所示, 有 3 种可以从 s 中得到 “rabbit” 的方案。
rabbbit
rabbbit
rabbbit

示例 2:

输入:s = “babgbag”, t = “bag”
输出:5
解释:
如下所示, 有 5 种可以从 s 中得到 “bag” 的方案。
babgbag
babgbag
babgbag
babgbag
babgbag

提示:

  • 1 <= s.length, t.length <= 1000
  • st 由英文字母组成
<2> 题解

1. 状态

本题虽然是困难题,但只要选好转移的状态,解答起来就比较简单了。

本题是要查询 s 中有多少种方法可以得到 t,比如第一个案例 s = “rabbbit”, t = “rabbit”,首先来考虑如何划分这个子问题:既然我去查询 s 有多少种方法可以得到 “rabbit” 比较困难,那能否先去找方法得到 “t” 呢?在之后能否得到 “it” 呢?

好,现在其实子问题的拆分就很明确了

  • s 中得到 “t” 有多少种方法?

  • s 中得到 “it” 有多少种方法?

  • s 中得到 “bit” 有多少种方法?

  • s 中得到 “bbit” 有多少种方法?

    。。。。。。

  • s 中得到 “rabbit” 有多少种方法?

这种考虑方式是从后往前去考虑的,其实也可以从前往后去转移。

那这个状态能否转移呢?

在这里插入图片描述

比如说现在要组成 BIT 这个序列,现在遍历到粉色的 B 了,现在,只需要知道,它后面的部分 能有几种方法组成 IT 就可以了。

2. dp 数组

本题需要一个二维的 dp 数组:

s = "rabbbit", t = "rabbit"

以上面的测试案例举例,dp[i][j] 表示目标字符串 t 从 i 到 末尾的字段在源字符串 s 从 j 到末尾的范围内有多少种构成的方式。

比如说 dp[3][0] 就是从 0 到 s.length - 1 这个范围内(“rabbbit”)构成 从 3 到 t.length - 1(“bit”)有几种方式。

3. 递推公式

还是举一个例子比较好理解:

比如说现在要计算这个节点,有多少种构成 BIT 的方式,就是要在这里寻找为 B 的节点

在这里插入图片描述

这时候它的前一层,也就是 dp[i + 1][j + 1] 表示从这个节点的后面开始,构成 IT 这个字段的方法

那这个节点构成 BIT 的方法就是 dp[i + 1][j + 1] 种嘛?是不对的,还需要再加上后一个节点构成 BIT 的方法,因为此时得到 BIT 的方法有如下两种:

在这里插入图片描述

所以最终得到的递推公式就是这样:

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

搞清楚递推公式的含义非常关键。

那对于不相等的情况:

在这里插入图片描述

比如这里的节点 A,那此时从 A 到末尾构成 BIT 的方法就是它后面那个节点构成 BIT 的方法,得到:

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

4. 初始化

因为本题的所有推导都是依赖第一行的,所以要先对第一行进行初始化

if (c1[c1.length - 1] == c2[c2.length - 1]) dp[c1.length - 1][c2.length - 1] = 1;for (int i = c2.length - 2; i >= 0; i--) {if (c2[i] == c1[c1.length - 1]) dp[c1.length - 1][i] = dp[c1.length - 1][i + 1] + 1;else dp[c1.length - 1][i] = dp[c1.length - 1][i + 1];}

先对最后一个元素进行特殊的处理,其他逻辑和前面的相同

<3> 代码
class Solution {public int numDistinct(String s, String t) {if (s.length() <= t.length()) {return s.equals(t) ? 1 : 0;}char[] c1 = t.toCharArray(); // 目标序列char[] c2 = s.toCharArray(); // 提供的序列int[][] dp = new int[c1.length][c2.length];if (c1[c1.length - 1] == c2[c2.length - 1]) dp[c1.length - 1][c2.length - 1] = 1;for (int i = c2.length - 2; i >= 0; i--) {if (c2[i] == c1[c1.length - 1]) dp[c1.length - 1][i] = dp[c1.length - 1][i + 1] + 1;else dp[c1.length - 1][i] = dp[c1.length - 1][i + 1];}for (int i = c1.length - 2; i >= 0; i--) {// 外层遍历要寻找的数组 c2for (int j = c2.length - 2; j >= 0; j--) {if (c1[i] == c2[j]) {dp[i][j] = dp[i + 1][j + 1] + dp[i][j + 1];} else {dp[i][j] = dp[i][j + 1];}}}return dp[0][0];}
}

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

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

相关文章

图片文件过大?尝试这些方法压缩图片大小!

​有时候我们会面临图片文件过大的问题&#xff0c;这不仅占用存储空间&#xff0c;还可能导致传输、上传和下载速度&#xff0c;本文将介绍一些实用的图片压缩方法&#xff0c;帮助我们压缩图片大小&#xff0c;同时保持良好的图像质量。 调整图像尺寸&#xff1a; 图像的尺…

【SpringSecurity】基础入门

目录 权限管理什么是权限管理认证授权权限管理解决方案Shiro开发者自定义Spring Security Spring Security特性Spring、Spring Boot 和 Spring Security 三者的关系整体架构1.认证AuthenticationManagerAuthenticationSecurityContextHolder 2.授权AccessDecisionManagerAccess…

卷起来——高级数据分析师

要成为一名高级数据分析师&#xff0c;需要掌握一系列的技能&#xff0c;包括数据处理、统计分析、机器学习、数据可视化以及业务理解等&#xff0c;喜欢或者想往这方面发展的童鞋们&#xff0c;卷起来&#xff0c;点击以下链接中的链接&#xff0c;备注"分析"进群交…

电商产品效果图渲染用什么工具更方便?

​在电子商务的快速发展中&#xff0c;产品的视觉呈现变得至关重要。对于电商行业的设计师而言&#xff0c;选择一款既便捷又高效的渲染工具&#xff0c;对于快速完成高质量的产品效果图至关重要。特别是对于初学者&#xff0c;工具的直观性和功能性是他们最为关注的焦点。 那…

【机器学习之旅】概念启程、步骤前行、分类掌握与实践落地

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

【MySQL】4.MySQL日志管理与数据库的备份和恢复

备份的目的只要是为了灾难恢复&#xff0c;备份还可以测试应用&#xff0c;回滚数据&#xff0c;修改和查询历史数据&#xff0c;审计等 日志在备份、恢复中起着重要作用 一、数据库备份的重要性 在生产环境中&#xff0c;数据的安全性至关重要 任何数据丢失都可能产生严重的…

详解U-Net分割网络,提供详细代码技术细节及完整项目代码

一. 原始模型整体概述 U-Net网络是Ronneberger等人在2015年发表于计算机医学影像顶刊 MICCAI上的一篇论文&#xff0c;该论文首次提出了一种U型结构来进行图像的语义分割&#xff0c;论文的下载链接如下&#xff1a;U-Net: Convolutional Networks for Biomedical Image Segme…

高中数学:抽象函数难点突破(拔高)

例题1 只证明前3个小题&#xff0c;4,5比较简单&#xff0c;不给与证明 这里&#xff0c;第3小题&#xff0c;难度最高 例题2 证明单调性的方法&#xff1a; 1、观察图像法&#xff1a;前提有具体解析式&#xff0c;且能画出图像 2、导数法&#xff1a;高三才学&#xff0c;且…

python和Vue开发的RBAC用户角色权限管理系统

后端框架&#xff1a;python的FastAPI作为后端服务和python-jose作为JWT认证 前端框架&#xff1a;Vue3构建页面和Vue Router作为路由管理&#xff0c;Pinia作为数据存储&#xff0c;Vite作为打包工具 可以实现菜单控制和路由控制&#xff0c;页面里面有按钮权限控制&#xf…

信息化平台管理系统智能引擎,互联网企业转型升级的新篇章-亿发

企业管理系统一直在伴随着中国互联网企业的发展而不断进步。过去&#xff0c;企业管理主要依赖于传统的表格和图表记录&#xff0c;但随着互联网企业的崛起&#xff0c;他们开始尝试自己开发简易的管理系统以满足业务需求。随着企业规模和业务复杂度的增加&#xff0c;互联网企…

【分享贴】多项目并行,如何做好项目管理?

对于项目经理来说&#xff0c;多项目并行管理是工作中的常态&#xff0c;也是一大难点。当多个项目共同推进时&#xff0c;项目经理经常会出现手忙脚乱、四处救火的情形&#xff0c;例如&#xff1a; A.资源管理难&#xff1a;资源冲突、资源分配不合理会导致项目延期。 B.进度…

【STM32嵌入式系统设计与开发】——12IWDG(独立看门狗应用)

这里写目录标题 一、任务描述二、任务实施1、ActiveBeep工程文件夹创建2、函数编辑&#xff08;1&#xff09;主函数编辑&#xff08;2&#xff09;USART1初始化函数(usart1_init())&#xff08;3&#xff09;USART数据发送函数&#xff08; USART1_Send_Data&#xff08;&…

苹果App Store上架工具介绍

文章目录 摘要引言正文1. Xcode2. [appuploder](https://www.applicationloader.net/)3. [克魔助手](https://keymob.com/) 4.[ipa guard](https://www.ipaguard.com/)总结参考资料 摘要 苹果App Store作为iOS应用程序的主要分发渠道&#xff0c;上架应用程序需要遵守规定和通…

Hive3.0.0出库库表中timestamp字段读取为null

在利用sqoop1.99.7做数据迁移的时候&#xff0c;从mysql导出表格到hive建立对应的表格&#xff0c;字段中使用了timestamp类型&#xff0c;在读取数据的时候&#xff0c;发现数据为null。查找问题方法如下&#xff1a; 1、查询库表字段类型 命令&#xff1a;desc tablen…

00000基础搭建vue+flask前后端分离项目

我完全是参考的这个vue3flask前后端分离环境速建_flask vue3-CSDN博客 安装了node_js&#xff08;添加了环境变量&#xff09; 环境变量 把原来的镜像源换成了淘宝镜像源 npm config set registry https://registry.npmmirror.com/ 查看版本证明安装成功 npm - v 安装npm i…

正则表达式不会用?一篇教你快速搞懂 !

目录 前言一、基础字符二、一系列常用的字符&#xff1b;1、一些元字符&#xff08;Meta-characters&#xff09; 三、一些高级概念1、贪婪与懒惰匹配2、两个实例加深理解1.颜色值的匹配&#xff1a;RGBS值2.ipv4 地址匹配 四、正则表达式常用语法**1.Flags&#xff08;标志符或…

c语言中动态内存管理

说到内存&#xff0c;大家一定都知道。但是有一种函数可以实现动态内存管理&#xff0c;下面大家一起学习。 文章目录 一、为什么要有动态内存管理&#xff1f;二、malloc 和 free1.malloc2.free 三、calloc 和 realloc1.calloc2.realloc3.常见的动态内存的错误3.1对NULL指针的…

面试题 之 webpack

1.说说你对webpack理解&#xff1f;解决什么问题&#xff1f; Webpack 是实现前端项目的模块化&#xff0c;用于现代 JavaScript 应用程序的静态模块打包工具&#xff0c;被webpack 直接引用的资源打包进 bunde.js的资源&#xff0c;当webpack 处理应用程序时,它会在内部构建一…

理解CPU与执行指令原理

本文侧重介绍cpu的工作任务&#xff0c;与cpu执行指令的过程是怎么样的&#xff1f; 目录 1.理解CPU 1.1.CPU的功能 1.2.CPU的逻辑构成 2.认识指令 2.1.什么是指令 2.2.CPU执行指令的准备工作(重点) 3.指令的执行过程 前景知识&#xff1a; 什么是计算机 就是遵循冯诺依…

阿里云部署宝塔,设置了安全组还是打不开。

1.在安全组是开放正确的端口好。8888要开&#xff0c;但是不只是开放8888&#xff0c;举个例子&#xff0c;https://47.99.53.222:17677/49706cf7这个&#xff0c;要开放17677这个端口号。 2.安全组要挂载到实例上&#xff0c;从三个点的进入点击管理实例&#xff0c;加到对应的…