力扣● 392.判断子序列 ● 115.不同的子序列

● 392.判断子序列

可以直接使用双指针的方法,2个指针分别从s、t开头出发,时间复杂度为O(t.size())。

但是这里用动规来做。Carl:掌握本题的动态规划解法是对后面要讲解的编辑距离的题目打下基础

so绕一下,用昨天的● 1143.最长公共子序列来写,dp[n1][n2]就是两个数组的最长公共子序列的长度,如果等于s.size()就是true。注意 ● 1143.最长公共子序列 是不以A[i-1]/B[j-1]为结尾的。因为是要求不连续子序列,所以不需要知道序列最后一个元素的值。

但是通过代码随想录,发现递推公式那还有可以改进的地方。

我们知道● 1143题,如果A[i-1]等于B[j-1]的话,dp[i][j]直接就是dp[i-1][j-1]+1。如果不相等的话, A[i-1]可能和B[j-1]之前的相等,B[j-1]可能和A[i-1]之前的相等,所以要取这两种情况的最大值:

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

学了昨天的不相交的线,可以知道这两种情况分别对应偏向左下的线和偏向右下的线,因为

● 1143.最长公共子序列 ● 1035.不相交的线 都没有说明2个字符串的长度谁大谁小,所以2种情况都有可能,但是这道题s比t短,只可能s[i-1]和t[j-1]之前的相等。所以画这一条线的话,只可能是垂直(dp[i-1][j-1]+1),或者偏向一个方向(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];

代码:

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

对比这三道题:● 1143.最长公共子序列; ● 1035.不相交的线;● 392.判断子序列

打印:

● 115.不同的子序列  

困难题,有点难理解。主要是dp数组的含义。

1.dp数组含义。

dp[i][j]:在s数组[0,i-1](可不以s[i-1]结尾)范围中出现t[0,j-1](必须以t[j-1]结尾)的个数为dp[i][j]。

2.递推公式。

因为不一定以s[i-1]结尾,所以相等不相等2种情况都要考虑:

(1)如果s[i-1]==t[j-1]。

根据dp数组定义,可以不以s[i-1]结尾。那么子序列又有2种情况:①以s[i-1]结尾。dp[i][j]代表的序列包含了s[i-1]和t[j-1],所以dp[i][j]应该继承了dp[i-1][j-1];②不以s[i-1]结尾,即不考虑s[i-1],那么t[j-1]出现在s[i-1]之前,根据dp定义,就应该从不包含s[i-1]的子数组[0,i-1]中出现t[0,j-1]的个数,得到dp[i][j],也就是dp[i-1][j]。

举例:bagag,bag。计算dp[4][2]的时候,s[4]=t[2],所以以s[4]结尾的话,可以在之前的序列ba里面加上s[4]:bagagbag。也可以不以s[4]结尾,那么不考虑s[4],从s的[0,3]里面找t[0,2]的个数,即选择s[4]之前的s[2]:bagagbag。所以这样就考虑了s数组里面可能会出现>=2个t[j-1]的情况。

分类加法分步乘法,这2种情况是分类的,会同时出现,且求的就是所有情况个数,所以相加。

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

(2)如果不等。

不相等的话,子序列肯定不会以s[i-1]结尾,所以直接不考虑s[i-1],继承不包含s[i-1]的连续子数组[0,i-1]中出现t[0,j-1]的个数即可。

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

3.初始化。

dp定义需贯穿始终。根据定义,i和j都只能从1开始,所以dp[0][j]和dp[i][0]都需要初始化。

dp[0][j]:s数组[0,0]里面包含t[0,j-1]的个数,如果j=0,没有意义。先看j>0,t非空,所以dp[0][j]肯定全为0。

dp[i][0]:s数组[0,i]里面包含t[0,-1]的个数,t[0,0]是t[0]这个元素,所以t[0,-1]代表的应该是空串。空串是否是字符串的子串?回忆子序列的定义:字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。所以空串就是将s所有元素都删除的子序列。想起数据结构说过空串是字符串的一个子串。

所以dp[i][0]应该初始化为1。

dp[0][0]也应该是1,空串也是空串的子序列。

4.遍历顺序。

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

5.打印。

代码:
 

class Solution {
public:int numDistinct(string s, string t) {int n1=s.size();int n2=t.size();vector<vector<long>> dp(n1+1,vector<long>(n2+1,0));for(int i=0;i<=n1;++i)dp[i][0]=1;for(int i=1;i<=n1;++i){for(int j=1;j<=n2;++j){if(s[i-1]==t[j-1])dp[i][j]=dp[i-1][j]+dp[i-1][j-1];else dp[i][j]=dp[i-1][j];dp[i][j]%=(int )(pow(10,9)+7);}}return dp[n1][n2];}
};

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

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

相关文章

直排开料机:木工行业的效率革命者

在木工行业中&#xff0c;开料机作为关键的生产设备&#xff0c;其选择直接关系到生产效率和产品质量。近年来&#xff0c;直排开料机以其独特的优势逐渐崭露头角&#xff0c;成为了众多企业的首选。那么&#xff0c;直排开料机究竟有哪些令人瞩目的优势呢&#xff1f; 一、高…

CrossOver24软件免费电脑虚拟机,快速在Mac和Linux上运行Windows软件

当然&#xff0c;除了之前提到的核心技术、兼容性和性能优化外&#xff0c;CrossOver2024还具有其他一些值得关注的性能特点&#xff1a; CrossOver Mac-安装包下载如下&#xff1a;https://wm.makeding.com/iclk/?zoneid50028 CrossOver linux-安装包下载如下&#xff1a;ht…

Spring Cloud Alibab 入门搭建,包含Nacos中心,注册服务发现服务,Feign请求,GateWay网关,sentinel限流

一、安装Nacos注册中心 1.1查看Nacos官网&#xff0c;安装Nacos服务&#xff0c;下载源码或者安装包 1.2启动服务&#xff0c;默认端口为8848&#xff0c; 二、创建服务注册&发现 2.1使用脚手架&#xff0c;创建注册服务和发现服务项目&#xff0c;我用的版本是2.6.13&…

mavros话题订阅后无法触发回调

前提 使用树莓派与pixhawk通信&#xff0c;安装好mavros&#xff0c;树莓派与pixhawk串口连接 启动节点mavros节点后&#xff0c;通过ros2 topic list可以查看到一系列话题 查看话题的类型可以去wiki mavros中查看 或者使用ros2 topic info 话题名称可以查看到 问题描述 订阅…

没有硬件基础可以学单片机吗?

没有硬件基础可以学单片机吗&#xff1f; 在开始前我分享下我的经历&#xff0c;我刚入行时遇到一个好公司和师父&#xff0c;给了我机会&#xff0c;一年时间从3k薪资涨到18k的&#xff0c; 我师父给了一些 电气工程师学习方法和资料&#xff0c;让我不断提升自己&#xff0c…

一.算法基础

目录 1.算法基础 2.算法概念 3.时间复杂度--用来评估算法运行效率的一个式子 如何简单快速的判断算法复杂度? 4.空间复杂度 1.算法基础 2.算法概念 --静态动态 3.时间复杂度--用来评估算法运行效率的一个式子 ----一个单位!!! 1-在什么配置下运行(机器) 2-问题的规模…

①【Docker】Linux安装Docker容器教程

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ ①【Docker】Linux安装Docker容器教程 &#x…

slf4j 打印当前类和方法

spring initializr 自动包含依赖,也可以在 pom.xml 文件中添加 slf4j 的依赖,指定版本 例如我这边默认版本是 1.7.36 通过添加依赖修改版本为 1.7.32<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version…

JavaScript数组sort自定义排序

背景 刷LeetCode时&#xff0c;遇到一道简单的数组排序题&#xff1a; 问题 想着直接用js的数组sort自定义排序即可&#xff0c;奈何测试用例运行总是不通过&#xff0c;返回的一直都是原数组。 代码排查 复制代码到Firefox浏览器控制台运行&#xff0c;结果输出的是正确结果&a…

Nginx的日志怎么看,在哪看,access.log日志内容详解

Nginx 的日志文件通常位于服务器的文件系统中&#xff0c;具体位置可能因配置而异。以下是查看 Nginx 日志的几种方法&#xff1a; 1、查看访问日志&#xff1a;在默认配置下&#xff0c;Nginx 的访问日志文件路径为 /var/log/nginx/access.log。您可以通过命令 sudo cat /var…

3、设计模式之工厂模式1(Factory)

工厂模式是什么&#xff1f;     工厂模式是一种创建者模式&#xff0c;用于封装和管理对象的创建&#xff0c;屏蔽了大量的创建细节&#xff0c;根据抽象程度不同&#xff0c;主要分为简单工厂模式、工厂方法模式以及抽象工厂模式。 简单工厂模式 看一个具体的需求 看一个…

Spring Boot 集成 WebSocket 实例 | 前端持续打印远程日志文件更新内容(模拟 tail 命令)

这个是我在 CSDN 的第一百篇原则博文&#xff0c;留念&#x1f60e; #1 需求说明 先说下项目结构&#xff0c;后端基于 Spring Boot 3&#xff0c;前端为 node.js 开发的控制台程序。现在希望能够在前端模拟 tail 命令&#xff0c;持续输出后端的日志文件。 #2 技术方案 #2.…

蓝桥杯练习:景区导游

视频 UP主的博客 暴力做法&#xff0c;能过 42%数据。如果内存开 1e410 能过 40%&#xff0c;如果开 2e510就只能过 25% #include<bits/stdc.h> #define int long long #define endl \n const int N 1e410; using namespace std; //存两点的距离 typedef pair<in…

豆瓣书影音存入Notion

使用Python将图书和影视数据存放入Notion中。 &#x1f5bc;️介绍 环境 Python 3.10 &#xff08;建议 3.11 及以上&#xff09;Pycharm / Vs Code / Vs Code Studio 项目结构 │ .env │ main.py - 主函数、执行程序 │ new_book.txt - 上一次更新书籍 │ new_video.…

全球首个 AI 软件工程师 Devin它来了!

如果您想每日获取AI最新新闻,欢迎关注文章底部的公众号 Cognition AI 发布 AI 软件工程师 Devin 初创公司 Cognition 近日发布公告,宣布推出全球首个 AI 软件工程师 Devin,并号称会彻底改变人类构建软件的方式。Devin 擅长长期推理能力,可以自主规划和完成软件项目,并在此…

ElasticSearch深度分页问题如何解决

文章目录 概述解决方法深度分页方式from size深度分页之scrollsearch_after 三种分页方式比较 概述 Elasticsearch 的深度分页问题是指在大数据集上进行大量分页查询时可能导致的性能下降和资源消耗增加的情况。这种情况通常发生在需要访问大量数据的情形下&#xff0c;比如用…

【OpenBayes 官方教程】数据读写绑定功能

本教程主要为大家介绍怎样在 OpenBayes 上进行数据的绑定以及如何使用已绑定的数据&#xff0c;新朋友点击下方链接注册后&#xff0c;即可获得 4 小时 RTX 4090 5 小时 CPU 的免费使用时长哦&#xff01; 注册链接 注册 - OpenBayes 首先&#xff0c;创建一个新的容器。 然…

非光滑非凸规划

目录 一&#xff0c;非凸函数的近端梯度下降 1&#xff0c;凸函数的近端梯度下降 2&#xff0c;非凸函数的近端梯度下降 一&#xff0c;非凸函数的近端梯度下降 1&#xff0c;凸函数的近端梯度下降 参考近端梯度下降 2&#xff0c;非凸函数的近端梯度下降

11.17定时调度(血干JAVA系类)

定时调度 11.17.1 Timer 类11.17.2 TimerTask 类11.17.3范例——定时操作【例11.52】建立TimerTask的子类【例11.53】建立测试类&#xff0c;进行任务调度 11.17.1 Timer 类 11.17.2 TimerTask 类 要想执行具体的任务&#xff0c;则必须使用Tim erTas k类。Tim erTas k类是一个…

工业界真实的推荐系统(小红书)-离散特征处理、矩阵补充模型、双塔模型

课程特点&#xff1a;系统、清晰、实用&#xff0c;原理和落地经验兼具 b站&#xff1a;https://www.bilibili.com/video/BV1HZ421U77y/?spm_id_from333.337.search-card.all.click&vd_sourceb60d8ab7e659b10ea6ea743ede0c5b48 讲义&#xff1a;https://github.com/wangsh…