力扣每日一题115:不同的子序列

news2024/11/15 13:43:08

题目

困难

给你两个字符串 s 和 t ,统计并返回在 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
  • s 和 t 由英文字母组成

面试中遇到过这道题?

1/5

通过次数

177K

提交次数

340.8K

通过率

51.9%

思路

注意!这是一道hard题!

看到xxx序列在xxx序列中xxx的个数、序列的最长xxx子序列、最长xxx串,最短xxx串这些题目,一眼就想到动态规划。

序列t在序列s的子序列中出现的次数,出现了两个序列的匹配,毫无疑问是二维dp,我们采用由前向后dp的思路,dp[i][j]来表示 t[1:i] 在 s[1:j] 的子序列中出现的次数。注意!由于动态规划一般要对边界值进行讨论,dp的下标从[1][1]开始,[0][……]和[……][0]用来做边界值的讨论。

对于这种两个字符串的动态规划,一般都是讨论 [i] 和 [j] 各自对应的字符是否相等来分类。

状态转移

1、如果t[i-1]!=s[j-1],也就是 i 对应的字符和 j 对应的字符不相等的情况。

要实现 t[1:i] 和 s[1:j] 的匹配,因为两部分切片的最后一个字符不相等,所有只能祈求 t[1:i] 能不能和 s[1:j-1]  能不能匹配。\thereforedp[i][j]=dp[i][j-1]。

2、t[i-1]==s[j-1]

两部分切片的最后一个字符相等,所以我们既可以选择两种匹配方法

a、t[i-1] 和 s[j-1] 匹配完成后,t[1:i-1]和t[1:j-1]匹配,这一部分的方案数量是 dp[i-1][j-1]

b、t[i-1]不和s[j-1]匹配,这时就和t[i-1]!=s[j-1]一样,这一部分方案数量就是 dp[i][j-1]

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

边界情况的讨论。

状态转移方程中,我们要用到dp[i-1][j-1],而我们的状态转移的循环是

        for(int i=1;i<=m;i++){
            for(int j=i;j<=n;j++){
                if(t[i-1]!=s[j-1]){
                    dp[i][j]=dp[i][j-1];
                }else{//t[i-1]和s[j-1]匹配+t[i-1]不和s[j-1]匹配
                    dp[i][j]=dp[i-1][j-1]+dp[i][j-1];
                }
            }
        }

m是t串的长度,n是s串的长度。

从循环上看,j<i||i==0 这一部分是没有出现在循环里的,但是i-1和j-1能遍历到,所以我们必然要讨论。

i=0时,代表切片为空串,空串是任何串的子串,所以这一部分的初值为1。

j<i时,s串长度小于t串,这是不可能是子串,所以这一部分初值为0。

        vector<vector<unsigned long long>> dp(m+1,vector<unsigned long long>(n+1,0));
        //边界情况-->空字符串是任何字符串的子序列
        for(int i=0;i<=n;i++){
            dp[0][i]=1;
        }

代码(注意数据范围和取模)

class Solution {
public:
    const int mod=1e9+7;
    int numDistinct(string s, string t) {
        int n=s.length();
        int m=t.length();
        if(n<m) return 0;
        //dp[i][j]-->t[1-i]在s[1-j]中出现的次数()
        //防止边界条件判断,从[1][1]开始算
        //long long都会超出数据范围
        vector<vector<unsigned long long>> dp(m+1,vector<unsigned long long>(n+1,0));
        //边界情况-->空字符串是任何字符串的子序列
        for(int i=0;i<=n;i++){
            dp[0][i]=1;
        }
        for(int i=1;i<=m;i++){
            for(int j=i;j<=n;j++){
                if(t[i-1]!=s[j-1]){
                    dp[i][j]=dp[i][j-1];
                }else{//t[i-1]和s[j-1]匹配+t[i-1]不和s[j-1]匹配
                    dp[i][j]=dp[i-1][j-1]+dp[i][j-1];
                }
            }
        }
        int ans=dp[m][n]%mod;
        return ans;
    }
};

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

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

相关文章

2024视觉与学习青年学者研讨会(VALSE 2024)热点推文预告

视觉与学习青年学者研讨会&#xff08;VALSE&#xff09;是国内人工智能领域顶尖学者一年一度的研讨会。该会议的特点是大、全、新。会议的规模大&#xff0c;参会者达到五千人以上&#xff1b;会议的主题全&#xff0c;全面覆盖人工智能的各大领域&#xff1b;会议的内容新&am…

CSS Web服务器、2D、动画和3D转换

Web服务器 我们自己写的网站只能自己访问浏览&#xff0c;但是如果想让其他人也浏览&#xff0c;可以将它放到服务器上。 什么是Web服务器 服务器(我们也会称之为主机)是提供计算服务的设备&#xff0c;它也是一台计算机。在网络环境下&#xff0c;根据服务器提供的服务类型不…

【arduino】库的安装方法

arduino 库的安装方法 假设你已经安装好 Arduino IDE 以 OneButton 为例来介绍几种安装方法 文章目录 arduino 库的安装方法方法一&#xff1a;直接安装法方法二&#xff1a;导入 .ZIP库方法三&#xff1a;将库文件夹直接复制到贡献库路径下方法四&#xff1a;将库文件夹直接…

JAVA学习14——异常

目录 异常&#xff1a; 1.异常基本介绍&#xff1a; 2.异常体系图&#xff1a; 3.五大运行时异常&#xff1a; &#xff08;1&#xff09;NullPointerException空指针异常&#xff1a; &#xff08;2&#xff09;AirthmetiException数字运算异常&#xff1a; &#xff0…

投资海外标的,首选跨境ETF!现在新开佣金低至万0.5!

全球资产配置的利器 随着经济的发展&#xff0c;全球资产配置成为中产阶级的关注方向。目前&#xff0c;全球资产配置的主要渠道包括直接开立境外账户、 QDII 基金、跨境 ETF 等。 现阶段通过跨境 ETF 投资境外股市是最便利、最具效率的方式之一。首先&#xff0c;与直接境外…

Gradle 基础学习(三) 认识Command-Line Interface

Gradle命令行接口 除了IDE外&#xff0c;我们主要通过Gradle命令行接口来运行Gradle任务和管理Gradle项目。 下面是Gradle命令行使用的一些参考&#xff0c;熟悉后建议实际项目中使用Gradle Wrapper&#xff0c;gradle用法都可以替换为gradlew (macOS / Linux) 或gradlew.bat…

LVGL移植到STM32F4

1、LVGL简介 LittlevGL是一个免费的开源图形库&#xff0c;提供了创建嵌入式GUI所需的一切&#xff0c;具有易于使用的图形元素、漂亮的视觉效果和低内存占用。 1.1、LVGL特点 强大的构建模组&#xff1a;按钮、图表、列表、滑块、图像等先进的图形&#xff1a;动画、反锯齿…

hadoop学习---基于Hive的数仓搭建增量信息拉链表的实现

拉链表就是SCD2&#xff0c;它的优点是即满足了反应数据的历史状态&#xff0c;又能在最大程度上节省存储。 拉链表的实现需要在原始字段基础上增加两个新字段&#xff1a; start_time(表示该条记录的生命周期开始时间——周期快照时的状态)end_time(该条记录的生命周期结束时…

家政保洁上门预约服务小程序源码系统 带完整的安装代码包以及搭建教程

随着社会的快速发展和人们生活节奏的加快&#xff0c;家政保洁服务已成为现代生活中不可或缺的一部分。为了满足广大用户的需求&#xff0c;罗峰给大家分享一款家政保洁上门预约服务小程序源码系统&#xff0c;该系统不仅提供完整的安装代码包&#xff0c;还附带详细的搭建教程…

ContEA阅读笔记

Facing Changes: Continual Entity Alignment for Growing Knowledge Graphs 面对变化&#xff1a;不断增长的知识图谱的持续实体对齐 Abstract 实体对齐是知识图谱(KG)集成中一项基本且重要的技术。多年来&#xff0c;实体对齐的研究一直基于知识图谱是静态的假设&#xff…

嵌入式学习——C语言基础——day14

1. 共用体 1.1 定义 union 共用名 { 数据类型1 成员变量1; 数据类型2 成员变量2; 数据类型3 成员变量3; .. }; 1.2 共用体和结构体的区别 1. 结构体每个成员变量空间独立 2. 共用体每个成员变量空间共享 1.3 判断内存大小端 1. 内存大端…

从零开始搭建Springboot项目脚手架2:配置文件、返回值、日志等

1、多个环境与配置文件 2、统一返回值 返回值包括两种场景&#xff1a;正常controller的返回、异常发生之后返回 正常controller的返回&#xff1a;通过在controller的默认返回Response实现 异常发生之后返回&#xff1a;通过全局异常处理统一捕获返回 首先创建类StatusCode…

php使用Canal监听msyql

canal需要java8 去官网下载java8 安装JAVA #创建目录 mkdir -p /usr/local/java/ #解压到目录 tar zxvf jdk-8u411-linux-x64.tar.gz -C /usr/local/java/配置环境变量在 /etc/profile 最后加入 export JAVA_HOME/usr/local/java/jdk1.8.0_411 export CLASSPATH.:$JAVA_HOM…

常用六大加密软件排行榜|好用加密文件软件分享

为了保障数据安全&#xff0c;越来越多的企业开始使用文件加密软件。哪款加密软件适合企业哪些办公场景呢&#xff1f; 今天就给大家推荐一下文件加密软件排行榜的前六名&#xff1a; 1.域智盾 这款软件专为企业和政府机构设计&#xff0c;提供全面的文件保护解决方案。 点…

typescript类型基础

typescript类型基础 枚举类型 enum Season {Spring,Summer,Fall,Winter }数值型枚举 enum Direction {Up,Down,Left,Right } const direction:Direction Direction.up每个数值型枚举成员都表示一个具体的数字&#xff0c;如果在定义一个枚举的时候没有设置枚举成员的值&…

InfiniGate自研网关实现三

9.网关注册中心服务初始创建 整理整个网关调用链路流程&#xff0c;梳理核心服务。并完成网关中心简单DDD模型结构工程的搭建&#xff0c;与库表连通可以查询接口映射数据。 在前面我已经开发出了一个初具模型的核心通信组件&#xff0c;那么我该如何使用这个组件呢&#xff…

私域流量引流方式有哪些?

私域流量引流的方法无非是营销渠道投放、各平台KOL投放、自有自媒体平台账号内容引流、线下引流、老客户转介绍裂变等几个方面&#xff0c;下面对各种不同方法进行简单介绍。 1、营销渠道投放&#xff1a;选择广点通、粉丝通、某些app的信息流和dou等大平台自带的推广渠道工具…

【Scala---04】函数式编程 『 函数 vs 方法 | 函数至简原则 | 函数式编程』

文章目录 1. 函数 vs 方法1.1 方法(1) 定义方法(2) 运算符即方法 1.2 函数(1) 定义函数(2) 匿名函数 1.3 方法转为函数1.4 可变参数&默认参数 2. 函数至简原则3. 函数式编程3.1 函数式编程思想3.3 函数柯里化&闭包3.5 递归 & 尾递归 4. 补充4.1 访问元祖元素4.2 &g…

揭秘“循环购”模式:为何商家如此慷慨,消费者又能获利?

亲爱的朋友们&#xff0c;我是吴军。今天&#xff0c;我将为大家揭开一种备受瞩目的商业模式——“循环购”的神秘面纱。你是否也好奇&#xff0c;为何商家愿意在你消费后给予丰厚的回馈&#xff0c;甚至让你在消费过程中还能赚取收益&#xff1f;这种模式的背后到底隐藏着什么…

Excel文件解析---超大Excel文件读写

1.使用POI写入 当我们想在Excel文件中写入100w条数据时&#xff0c;使用XSSFWorkbook进行写入时会发现&#xff0c;只有将100w条数据全部加载到内存后才会用write()方法统一写入&#xff0c;效率很低&#xff0c;所以我们引入了SXXFWorkbook进行超大Excel文件读写。 通过设置 …