代码随想录算法训练营第五十五天 | 392.判断子序列、115.不同的子序列

news2024/10/7 4:04:48

打卡第55天。

今日任务

  • 392.判断子序列
  • 115.不同的子序列

392.判断子序列

给定字符串 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
  • 两个字符串都只由小写字符组成。

我的题解

暴力解决

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int k = -1; int cnt = 0;
        for(int i = 0; i < s.size(); i++) {
            for(int j = k + 1; j < t.size(); j++) {
                if(s[i] == t[j]) {
                    k = j;
                    cnt++;
                    break;
                } else {
                    k = -1;
                }
            }
            if(k == -1 || s[i] != t[k]) return false;  
        }
        if(k + 1 == t.size() && cnt != s.size()) return false;
        return true;
    }
};

双指针做法

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int i = 0;
        for(int j = 0; j < t.size(); j++) {
            if(s[i] == t[j]) i++;
        }
        
        return i == s.size();
    }
};

代码随想录

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

  2. 递推公式
    在确定递推公式的时候,首先要考虑如下两种操作,整理如下:

    • i f ( s [ i − 1 ] = = t [ j − 1 ] ) if (s[i - 1] == t[j - 1]) if(s[i1]==t[j1])t中找到了一个字符在s中也出现了
    • i f ( s [ i − 1 ] ! = t [ j − 1 ] ) if (s[i - 1] != t[j - 1]) if(s[i1]!=t[j1])相当于t要删除元素,继续匹配

    i f ( s [ i − 1 ] = = t [ j − 1 ] ) if (s[i - 1] == t[j - 1]) if(s[i1]==t[j1]),那么 d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + 1 ; dp[i][j] = dp[i - 1][j - 1] + 1; dp[i][j]=dp[i1][j1]+1;,因为找到了一个相同的字符,相同子序列长度自然要在dp[i-1][j-1]的基础上加1(如果不理解,在回看一下dp[i][j]的定义)

    i f ( s [ i − 1 ] ! = t [ j − 1 ] ) if (s[i - 1] != t[j - 1]) if(s[i1]!=t[j1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即: d p [ i ] [ j ] = d p [ i ] [ j − 1 ] ; dp[i][j] = dp[i][j - 1]; dp[i][j]=dp[i][j1];

    其实这里 大家可以发现和 1143.最长公共子序列的递推公式基本那就是一样的,区别就是 本题 如果删元素一定是字符串t,而 1143.最长公共子序列 是两个字符串都可以删元素。

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int n = s.size(), m = t.size();
        vector<vector<int> > dp(n + 1, vector<int>(m + 1, 0)); //dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j];
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(s[i - 1] == t[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
                // else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                else dp[i][j] = dp[i][j - 1];
            }
        }
        return dp[n][m] == n;
    }
};

115.不同的子序列

给你两个字符串 st ,统计并返回在 s子序列t 出现的个数。

题目数据保证答案符合 32 位带符号整数范围。

示例 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 由英文字母组成

代码随想录

  1. dp以及下标定义
    dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。

  2. 递推公式
    这一类问题,基本是要分析两种情况

    • s[i - 1] 与 t[j - 1]相等
    • s[i - 1] 与 t[j - 1] 不相等

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

    • 一部分是用s[i - 1]来匹配,那么个数为dp[i - 1][j - 1]。即不需要考虑当前s子串和t子串的最后一位字母,所以只需要 dp[i-1][j-1]。
    • 一部分是不用s[i - 1]来匹配,个数为dp[i - 1][j]。
      当s[i - 1] 与 t[j - 1]不相等时,dp[i][j]只有一部分组成,不用s[i - 1]来匹配(就是模拟在s中删除这个元素),即:dp[i - 1][j]。
  3. 初始化
    从递推公式dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]; 和 dp[i][j] = dp[i - 1][j]; 中可以看出dp[i][j] 是从上方和左上方推导而来。

    • dp[i][0] 表示:以 i-1 为结尾的s可以随便删除元素,出现空字符串的个数。一定都是1,因为也就是把以i-1为结尾的s,删除所有元素,出现空字符串的个数就是1。
    • dp[0][j]:空字符串s可以随便删除元素,出现以j-1为结尾的字符串t的个数。dp[0][j]:空字符串s可以随便删除元素,出现以j-1为结尾的字符串t的个数。
    • 特殊:dp[0][0]应该是1,空字符串s,可以删除0个元素,变成空字符串t。
  4. 遍历顺序
    从递推公式中可以看出dp[i][j]都是根据左上方和正上方推出来的。所以遍历的时候一定是从上到下,从左到右

  5. 举例dp数组
    在这里插入图片描述

class Solution {
public:
    int numDistinct(string s, string t) {
        int n = s.size(), m = t.size();
        vector<vector<uint64_t> > dp(n + 1, vector<uint64_t>(m + 1, 0)); // p[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。
        for (int i = 0; i <= n; i++) dp[i][0] = 1;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; 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[n][m];
    }
};

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

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

相关文章

哪个品牌的蓝牙耳机便宜耐用?内行公认四大便宜耐用的蓝牙耳机

蓝牙耳机发展至今&#xff0c;品牌众多&#xff0c;且各品牌旗下拥有无数不同价格的耳机&#xff0c;各自的主打优势又不一样。那么&#xff0c;哪个品牌的蓝牙耳机便宜耐用&#xff1f;下面&#xff0c;我来给大家推荐四款便宜耐用的蓝牙耳机&#xff0c;一起来看看吧。 一、…

【数据结构】第九站:树和二叉树

目录 一、树的概念及结构 1.树的概念 2.树的相关概念 3.树的表示 二、二叉树的概念及结构 1.概念 2.特殊的二叉树 3.二叉树的性质 三、二叉树的存储结构 一、树的概念及结构 1.树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个…

Redis缓冲区溢出及解决方案

缓冲区(buffer)&#xff0c;是内存空间的一部分。也就是说&#xff0c;在内存空间中预留了一定的存储空间&#xff0c;这些存储空间用来缓冲输入或输出的数据&#xff0c;这部分预留的空间就叫做缓冲区。 一、Redis缓冲区溢出影响 在Redis中&#xff0c;主要有三个场景用到了…

数据资产目录建设方法

以信息技术为核心的第四次经济革命使得全球经济进入到数字化转型时期&#xff0c;对于今天的企业来说&#xff0c; 数字化转型已经不是可做可不做的自选题&#xff0c; 而是必须付诸行动的必选题。 从数字化转型的实践经验中我们可以得知&#xff0c;企业的数据资产是企业数字…

Flink CDC 在京东的探索与实践

摘要&#xff1a;本文整理自京东资深技术专家韩飞&#xff0c;在 Flink Forward Asia 2022 数据集成专场的分享。本篇内容主要分为四个部分&#xff1a; 京东自研 CDC 介绍京东场景的 Flink CDC 优化业务案例未来规划点击查看直播回放和演讲 PPT 一、京东自研 CDC 介绍 京东自研…

pdf转换成word怎么转换?这个方法一学就会!

在日常工作和生活中&#xff0c;我们常常会遇到需要将PDF文件转换为Word文档的情况。这个过程有时候会令人感到麻烦和心累&#xff0c;需要特殊操作才能完成。但实际上&#xff0c;通过选择正确的方法&#xff0c;文件格式转换只需要几秒钟的时间。如果你感到不可思议&#xff…

ChatGPT-4 来了,附国内体验地址

chatgpt4是什么&#xff1f; 2022年12月&#xff0c;openAI发布了chatgpt模型&#xff0c;这个属于GPT-3.5系列模型中的一个。上个月&#xff0c;openAI又发布了超级升级版的GPT-4模型。所以&#xff0c;你想问的chatgpt4模型是指代GPT-4模型。 相比前一个版本&#xff0c;它…

智能硬件蓝牙配网方案概要

智能硬件开发系列 Google Protobuf 实践使用开发智能硬件蓝牙配网方案概要JNI开发必学C基础JNI开发必学C使用实践Android Studio 4.0.NDK项目开发详细教学Android NDK与JNI的区别有何不同&#xff1f;Android Studio 4.0.NDK .so库生成打包Android JNI的深度进阶学习Android S…

【Leetcode】题库-爽刷简单题(1)

目录 写在前面&#xff1a; 题目&#xff1a;67. 二进制求和 - 力扣&#xff08;Leetcode&#xff09; 解题思路&#xff1a; 代码&#xff1a; 过过过过过过啦&#xff01;&#xff01;&#xff01;&#xff01; 题目&#xff1a;83. 删除排序链表中的重复元素 - 力扣&a…

linux之jdk1.8环境安装与配置和Maven安装与配置

文章目录一、jdk1.8环境安装1、官网下载&#xff1a;<https://www.oracle.com/java/technologies/downloads/#java8>2、在usr文件夹下新建一个java文件夹3、解压完成后&#xff0c;将文件jdk文件传入到java目录下二、配置环境&#xff08;重点&#xff09;1、按 i 进行编…

docker环境下搭建rocketmq集群

rocketmq是一个分布式消息中间件&#xff0c;分布式的意思就是多台机器可以通过网络连接协同工作&#xff0c;因此rocketmq可以运行在多台机器上&#xff0c;以达到超越单机的服务能力。rocketmq的架构图如下所示 我们首先搭建一个最小的rocketmq集群&#xff0c;需要启动一个n…

MySQL安装配置与连接Navicat

本文详细记录win11系统MySQL安装配置与Navicat连接过程&#xff0c;每个知识点都解释了&#xff0c;不止安好了&#xff0c;你还学懂了&#xff01;你不知道选择哪个版本&#xff0c;不知道参数啥意思&#xff0c;不知道哪种安装方式好&#xff1f;这里都有答案&#xff01;&am…

最大二叉树

1题目 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。 递归地在最大值 左边 的 子数组前缀上 构建左子树。 递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回 nums 构建的 最…

六、Locust之TaskSets详解

​ TaskSets是一种结构化测试分层网站/系统的方法。你可以在这里阅读更多关于它的信息。 1.TaskSet class ​ 如果你正在对一个以分层方式构建的网站进行性能测试&#xff0c;有章节和子章节&#xff0c;以同样的方式构建你的负载测试可能是有用的。 ​ 为了这个目的&#x…

全终端办公电子邮件集成方案

面临挑战 应用场景复杂&#xff0c;经常需要在不同终端进行切换&#xff0c;多屏、跨屏及移动办公要求高&#xff1b; 业务系统较多&#xff0c;需要同时支持多种业务的开展&#xff0c;对第三方应用集成及协同办公要求高&#xff1b; 对邮件系统的稳定及高效性要求高&#x…

【Linux】线程中的互斥锁、条件变量、信号量(数据安全问题、生产消费模型、阻塞队列和环形队列的实现)

文章目录1、线程互斥1.1 线程间频繁切换导致的问题1.2 使用互斥锁1.3 互斥锁的原理1.4 线程中的数据安全问题2、线程同步之条件变量2.1 生产消费模型2.2 条件变量概念和调用函数2.3 阻塞队列的实现3、线程同步之信号量3.1 理解信号量3.2 信号量接口3.3 环形队列的实现4、小结1、…

[golang gin框架] 23.Gin 商城项目-前台templates模板分离,首页,顶部导航,轮播图 左侧分类数据渲染

一.首页界面展示以及项目结构分析首页界面展示项目结构分析二.代码展示首页相关模型首页相关模型如下:[golang gin框架] 21.Gin 商城项目-导航模块功能[golang gin框架] 17.Gin 商城项目-商品分类模块, 商品类型模块,商品类型属性模块功能操作[golang gin框架] 16.Gin 商城项目…

2023中国程序员薪酬报告出炉,你拖后腿了吗?

程序员薪资高已是公认的事实&#xff0c;但是具体高到什么程度呢&#xff1f;近期&#xff0c;全球人力服务公司 Michael Page Internatioal 就发布了《2023 中国大陆薪酬报告》&#xff0c;揭示了中国程序员的薪酬情况。 该报告中一共调研了国内 7 个行业以及 6 大城市不同职…

Doris的基本概述

目录 Doris是什么 使用场景 技术概述 Doris是什么 由百度大数据部研发&#xff0c;之前加做百度palo&#xff0c;20118年共享到Apache社区后&#xff0c;更名Doris一个现代化的MPP分析型数据库产品 支持压秒级别响应架构非常简洁&#xff0c;易于运维支持10PB以上的超大数据…

企业数字化转型全是坑?这几篇数字化转型成功案例,减少70%损失

这篇给大家整理了200企业数字化转型案例合集&#xff0c;涵盖了制造、建筑、教育、零售、互联网等10行业的大中小型企业数字化转型思路&#xff0c;希望对大家有所帮助。 案例全部整合在这篇文章中&#xff0c;点击即可查看>>数字化干货资料合集&#xff01; 01 首先&…