当前位置: 首页 > news >正文

【算法练习Day46】判断子序列不同的子序列

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 判断子序列
  • 不同的子序列
  • 总结:

判断子序列

392. 判断子序列 - 力扣(LeetCode)

判断子序列这道题目,和上一期的题解法几乎完全相同,只是递推公式有一点差别,但是要是完全用之前的代码也是可行的。

dp数组的含义:dp【i】【j】代表以i-1和j-1为结尾的相同子序列的长度。之前我们讲过,同时操作两个数组的时候,通常都是设置二维数组。设置为i-1和j-1表示的原因是,方便数组初始化。

递推公式:当两个字符相等时候

if(s【i-1】==t【j-1】)dp【i】【j】=dp【i-1】【j-1】+1;

因为dp数组含义的缘故,我们在判断时候对应的也是它的字符串的i-1位置和j-1位置,然后如果两字符此时对应相等,那么就是之前最大的相同子序列的长度+1。

else dp【i】【j】=dp【i】【j-1】;

如果两字符不相等,那么就让此时的对应的do等于 dp【i】【j-1】,这是因为我们是判断s是否为t的子序列,是删除t中某些元素看看能否构成s,已知此时两对应字符一定不相等,那此时dp就等于不考虑当前这个不等的字符时,所对应的最长相同子序列长度,这样做也相当于变相删除该多余字符。细心的读者也许已经发现了,与之前那期递推公式不同的是没有dp【i-1】【j】这一项了,之前的递推公式是它们两个取最大值,那是因为上一道题两个字符都可以删除若干数据,而最终保证结果是最长的公共部分就可以了,不一定给的哪个字符串更长,所以删哪一个也就不一定了,需要取最大值,而这道题我们是明确的判断s是否是t的子序列,那就是t长要删除某元素后看是否构成s。至于为什么我说用和之前一样的代码也能通过呢?因为我们不需要删除s的元素,也就是说加上它也不会影响代码的运行逻辑,但是建议还是要根据题目的需求写逻辑,而不是这类题都用一种固定的递推公式来写,这样多思考更有利于理解题的本质。

dp数组初始化:dp数组初始化就是全都是0没什么说的,由于dp定义的缘故,和递推公式的推理,都使得,应该被初始化为0。

遍历顺序:还是正常的从左到右从上到下。

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)

与上一道题的相比,这道题显得难了不少。也是困扰了我一段时间的题,感觉递推公式不是很好理解。

dp数组含义:这道题是判断在s里t出现的次数有多少次,这道题并不是说直观的就能看出s字符串里有几个t,不要曲解题目意思,它是说有多少种删除元素的方法,使得字符串由s转化为t,应该这样去理解。所以应该将数组含义定义为以i-1结尾的字符串s中包含有以j-1为结尾的t多少个。这个dp数组定义非常重要,要好好理解,才能够理解下面的递推公式。

递推公式:递推公式由两部分组成,和上一题一样,一个是要匹配的字符匹配,另一个字符不匹配,要模拟删除,而不同的是这道题里能够相匹配的字符递推公式,也分成两部分。

经过了一段时间的理解,我觉得这样想是能够帮助理解递推式的。

如果两字符不匹配,那么dp【i】【j】=dp【i-1】【j】因为我们上面说过dp数组的含义,表示的是前一个位置,当前一个位置不匹配字符,那么说明此时应该和同一列的上一行所代表的个数相等,为什么是这样呢?画dp数组推到图也就是打印,我们可以知道,s表示行t表示列时候,此时s对应的字符和t不等,那么就应该此处的数值继承下来上一次匹配成功的值,虽然它的同列上一行也可能不匹配,但是它的上一处也是继承的匹配成功的那个个数。我们是拿着s的字符一点点找t的字符去匹配,如果还是不明白,画一次会帮助理解。

那如果两字符相匹配呢?我们不仅仅要保留之前的匹配不成功的所继承下来的个数,还要加上此次匹配成功时候应该加上的个数,而上一次怕匹配成功是哪一个位置?是dp【i-1】【j-1】也就是我们要填写的位置的左上角,,它是匹配成功的时候所继承下来的含有个数,两者一做和就能得到答案了,所以递推公式是:

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】

一开始怎么也想不明白为什么,要这么写,后来换一种思维去想,就能想得明白了。

dp数组初始化:初始化也是有一定讲究的,虽然我们是定义的i-1和j-1的位置,但此题并不意味着要全部初始化为0,因为我们是求得s里有几个t,当t是空字符串时候,每一个i-1下标都对应着一种方法得到t,那就是删除i-1之前的全部字符,得到一个空字符串。s是空字符串时候,无论怎么删都不可能得到一个t,而且其他的位置都会被递推公式所覆盖,所以除了第一行之外全都初始化为0就可以了,第一行初始化为1。

遍历顺序:根据递推公式得到,i,j位置由它的上面位置和左上位置推导,所以依旧是从上到下从左到右

class Solution {
public:int numDistinct(string s, string t) {vector<vector<unsigned long int>>dp(s.size()+1,vector<unsigned long int>(t.size()+1,0));dp[0][0]=1;for(int i=1;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];//可以理解为dp二维数组即使本次匹配字符未成功//它也至少是上一次匹配的个数,因为dp数组的定义就是s字符串i-1位置下,对应的有几个t//本次即使未匹配成功,也不应该影响之前匹配成功保留下来的次数。//而如果匹配成功,那么就是两个字符匹配的成功个数加上本来有的个数else dp[i][j]=dp[i-1][j];}}return dp[s.size()][t.size()];}
};

总结:

今天我们完成了判断子序列、不同的子序列两道题,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

相关文章:

【算法练习Day46】判断子序列不同的子序列

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 判断子序列不同的子序列总结…...

Java设计模式之访问者模式

目录 定义 结构 案例 优点 缺点 使用场景 扩展 分派 案例实现须知 动态分派 静态分派 双分派 定义 封装一些作用于某种数据结构中的各元素的操作&#xff0c;它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。 结构 访问者模式包含以下主要角色…...

PySide/PYQT如何用Qt Designer和代码来设置文字属性,如何设置文字颜色?

文章目录 📖 介绍 📖🏡 环境 🏡📒 实现方法 📒📝 Qt Designer设置📝 代码📖 介绍 📖 本人介绍如何使用Qt Designer/代码来设置字体属性(包含字体颜色) 🏡 环境 🏡 本文使用Pyside6来进行演示📒 实现方法 📒 📝 Qt Designer设置 首先打开Qt De…...

ubuntu 设置最大带宽

背景 近日做实验&#xff0c;需要限制一些机子的带宽以达到模拟的效果。在网上搜索了一阵子&#xff0c;结合自己实操的经验&#xff0c;潦草写下这篇文章&#xff0c;供自己与有需要的人参考。 环境&#xff1a; Ubuntu 22.04.1 LTS 安装 wondershaper 和 speedtest-cli w…...

如何在 Python 中执行 MySQL 结果限制和分页查询

Python MySQL 限制结果 限制结果数量 示例 1: 获取您自己的 Python 服务器 选择 “customers” 表中的前 5 条记录&#xff1a; import mysql.connectormydb mysql.connector.connect(host"localhost",user"您的用户名",password"您的密码"…...

Django配置文件,request,链接mysql方法,Orm简介

三板斧问题(views.py) HttpResponse # 返回的是字符串render # 渲染一个HTML静态文件&#xff0c;模板文件redirect # 重定向的 在视图文件中得视图函数必须要接收一个形参request&#xff0c;并且&#xff0c;视图函数也要有返回值&#xff…...

ubuntu下载各个版本chrome方法

Ubuntu/debian 在这里面找版本 https://unix.stackexchange.com/a/612981然后添充进去 http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_[HERE_THE_FULL_VERSION]_amd64.deb比如&#xff1a;https://dl.google.com/linux/chro…...

Http状态码502常见原因及排错思路(实战)

Http状态码502常见原因及排错思路 502表示Bad Gateway。当Nginx返回502错误时&#xff0c;通常表示Nginx作为代理服务器无法从上游服务器&#xff08;如&#xff1a;我们的后端服务器地址&#xff09;获取有效的响应。导致这种情况的原因有很多&#xff1a; 后端服务器故障ngin…...

国际阿里云:无法ping通ECS实例公网IP的排查方法!!!

无法ping通ECS实例的原因较多&#xff0c;您可以参考本文进行排查。 问题现象 本地客户端无法ping通目标ECS实例公网IP&#xff0c;例如&#xff1a; 本地客户端为Linux系统&#xff0c;ping目标ECS实例公网IP时无响应&#xff0c;如下所示&#xff1a; 本地客户端为Windo…...

Nginx缓存基础

1 nginx缓存的流程 客户端需要访问服务器的数据时&#xff0c;如果都直接向服务器发送请求&#xff0c;服务器接收过多的请求&#xff0c;压力会比较大&#xff0c;也比较耗时&#xff1b;而如果在nginx缓存一定的数据&#xff0c;使客户端向基于nginx的代理服务器发送请求&…...

【数据结构】Lambda

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈数据结构 &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; Lambda表达式 1. 背景1.1 语法1.2 函…...

力扣labuladong——一刷day28

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣380. O(1) 时间插入、删除和获取随机元素二、力扣710. 黑名单中的随机数 前言 常数时间删除-查找数组中的任意元素&#xff0c;且随机访问概率一致 如果…...

2023年CCF非专业级别软件能力认证第二轮 (CSP-S)提高级C++语言试题

2023年CCF非专业级别软件能力认证第二轮 &#xff08;CSP-S&#xff09;提高级C语言试题 编程题第 1 题 问答题 密码锁&#xff08;lock&#xff09; 题目描述 小Y有一把五个拨圈的密码锁。如图所示&#xff0c;每个拨圈上是从0到9的数字。每个拨圈都是从0到9的循环&#xf…...

华为ensp:静态默认路由

静态路由 到r2 上的系统视图模式 下一跳为1.1.1.2 ip route-static 192.168.2.0 255.255.255.0 1.1.1.2 如果找2网段下一跳为1.1.1.2接口 默认路由 到r3上做的是默认路由 ip route-static 0.0.0.0 0 1.1.1.1 所有的流量去找1.1.1.1 查看效果 只要做完完整的路由就可…...

xss 通过秘籍

终极测试代码 <sCr<ScRiPt>IPT>OonN"\/(hrHRefEF)</sCr</ScRiPt>IPT> 第一关&#xff08;没有任何过滤&#xff09; 使用终极测试代码&#xff0c;查看源码 发现没有任何过滤&#xff0c;直接使用javascrupt中的alert弹框 <script>aler…...

Kibana使用Watcher监控服务日志并发送飞书报警(Markdown)

Watcher是什么 Kibana Watcher 是 Elasticsearch 的监控和告警工具&#xff0c;它允许你设置和管理告警规则以监控 Elasticsearch 数据和集群的状态。Kibana Watcher 可以监测各种指标和数据&#xff0c;然后在满足特定条件时触发警报。它提供了一种强大的方式来实时监控 Elas…...

Flutter笔记:光影动画按钮、滚动图标卡片组等

Flutter笔记 scale_design更新&#xff1a;光影动画按钮、滚动图标卡片组 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263…...

【论文】利用移动性的比例公平蜂窝调度测量和算法

&#xff08;一支笔一包烟&#xff0c;一节论文看一天 &#xff09;&#xff08;一张纸一瓶酒&#xff0c;一道公式推一宿&#xff09; 摘要1. 引言2. 相关工作3. 模型和问题公式4. 预测FPF调度 &#xff08; P F &#xff09; 2 S &#xff08;PF&#xff09;^2S &#xff08;…...

内存条选购注意事项(电脑,笔记本)

电脑内存条的作用、选购技巧以及注意事项详解 - 郝光明的个人空间 - OSCHINA - 中文开源技术交流社区 现在的电脑直接和内存条联系 电脑上的所有输入和输出都只能依靠内存条 现在买双条而不是单条 买两个相同的内存条最好 笔记本先分清是低电压还是标准电压&#xff0c;DD…...

ChatGPT 宕机?OpenAI 将中断归咎于 DDoS 攻击

您的 ChatGPT 已关闭吗&#xff1f;您是否遇到 ChatGPT 问题&#xff0c;例如连接问题或遇到“长响应时出现网络错误”&#xff1f;– ChatGPT 遭受了一系列 DDoS 攻击&#xff0c;显然是由匿名苏丹组织策划的。 OpenAI 的 ChatGPT 是一款流行的人工智能聊天机器人&#xff0c;…...

保姆级教程:在Linux上用Neo4j 3.5.35社区版搭建你的第一个图数据库(附配置文件修改详解)

从零开始&#xff1a;Linux环境下Neo4j 3.5.35社区版实战部署指南 第一次接触图数据库时&#xff0c;那种既兴奋又忐忑的心情我至今记忆犹新。作为非关系型数据库中的重要分支&#xff0c;图数据库以其独特的节点-关系模型&#xff0c;在处理复杂关联数据时展现出惊人的效率。而…...

2025年Scratch图形化编程三级考试真题解析与备考策略

1. 2025年Scratch三级考试真题深度解析 最近帮几个小朋友准备Scratch三级考试&#xff0c;发现很多孩子做题时容易陷入"看着会做但总选错"的困境。就拿2025年6月这套真题来说&#xff0c;表面看都是基础题&#xff0c;但每道题都藏着几个易错点。比如第一题的多边形绘…...

ESP8266嵌入式MQTT Broker:本地AP+WebSocket轻量实现

1. 项目概述MQTTbroker 是一款专为 ESP8266 设计的轻量级嵌入式 MQTT 消息代理&#xff08;Broker&#xff09;实现&#xff0c;其核心目标是消除云中转依赖&#xff0c;构建本地闭环物联网控制链路。该库并非通用型 MQTT 服务器&#xff08;如 Mosquitto 或 EMQX&#xff09;&…...

从零开始掌握YOLO——实时目标检测的技术详解

你正在打开手机相册,系统自动把所有照片按“人物”“风景”“宠物”整理好;你开车经过十字路口,路边的摄像头精准识别出车牌和车型;工厂流水线上,机械臂的“眼睛”实时锁定每一个瑕疵品——这些场景背后,几乎都站着一个名字:YOLO。 YOLO(You Only Look Once)自2015年…...

Tauri 2.0 Shell插件避坑指南:预设参数覆盖、权限配置与Command.create的正确姿势

Tauri 2.0 Shell插件深度实战&#xff1a;参数控制、权限设计与Command最佳实践 当你在Tauri项目中尝试通过Shell插件调用外部程序时&#xff0c;是否遇到过参数莫名失效、权限配置不生效的困扰&#xff1f;本文将带你深入tauri-apps/plugin-shell的设计哲学&#xff0c;通过真…...

GyverWire:嵌入式轻量级通用串行通信框架

1. GyverWire&#xff1a;面向嵌入式系统的轻量级、高鲁棒性通用串行通信框架GyverWire 是一款专为资源受限嵌入式平台&#xff08;尤其是 Arduino 生态&#xff09;设计的底层通信库&#xff0c;其核心目标并非实现某一种特定物理层协议&#xff0c;而是提供一个可复用、可扩展…...

【2026 深度】开发者如何利用全链路追踪,解决自动化脚本与多端引流的“黑盒”问题?

. 前言&#xff1a;当自动化脚本遇到“数据断层”作为开发者&#xff0c;我们经常会编写各种自动化脚本&#xff08;如 Node.js 镜像同步、Rust 编译分发&#xff09;&#xff0c;或者在社交平台分发技术工具。但在 2026 年&#xff0c;单纯的“流量”已经没用了&#xff0c;**…...

Keyence VT5 HMI嵌入式通信库:RS232协议栈实现

1. KeyenceHMI_Lib 库深度解析&#xff1a;面向工业现场的 RS232 HMI 通信协议栈实现1.1 工程定位与核心价值KeyenceHMI_Lib 是一个专为嵌入式平台&#xff08;特别是 Arduino 生态&#xff09;设计的轻量级通信库&#xff0c;其核心目标是在资源受限的微控制器上&#xff0c;可…...

ArduLog:ESP32/ESP8266轻量级嵌入式日志库

1. ArduLog&#xff1a;面向ESP8266/ESP32的轻量级嵌入式日志库深度解析1.1 设计定位与工程价值ArduLog并非通用日志框架&#xff0c;而是专为资源受限型Wi-Fi SoC&#xff08;ESP8266/ESP32&#xff09;定制的裸机友好型调试日志工具。其核心设计哲学可概括为三点&#xff1a;…...

uniapp消息推送权限处理指南:如何优雅地引导用户开启通知权限

Uniapp消息推送权限优化实战&#xff1a;从检测到引导的全链路设计 移动应用的消息推送功能直接影响用户活跃度和留存率&#xff0c;但很多开发者忽略了权限引导这一关键环节。据统计&#xff0c;超过40%的用户首次安装应用时会默认关闭通知权限&#xff0c;导致重要消息无法触…...