LeetCode 115.不同的子序列 详解
题目详情
给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数。
一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,“ACE” 是 “ABCDE” 的一个子序列,而 “AEC” 不是)
示例 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
^^^
题目详解
动态规划关键是找到递推公式, 而找到递推公式,首先就是要找到如何表示数组dp 然后找到递推关系。
我们可以发现。此题和编辑距离一样。都是由两个字符串, 是从一个字符串变到另一个字符串, 对于编辑距离这个题是在字符串1进行增, 删, 改操作变到字符串2, 此题是在字符串1里找到字符串2。
所以对于此题我们先构造dp, 类似于编辑距离, 定义dp[i][j],表示字符串1的从0开始长度为i的字符串, 和字符串2的从长度为j的字符串, 这两个字符串匹配的个数。
下面就是要找递推式了
首先开始可能递推看不出来, 所以有些做法就是写一个例子, 然后把例子的dp全部写出来, 这里就以题目的S = “rabbbit”, T = "rabbit"例子

观察到
- 最终结果是dp[S.size()][T.size()]
- 每当S[i] == T[j]时, dp[i][j]会增加, 比如S = rabb, T = rab. 此时dp[i][j] = dp[i][j-1] + x (x为增加量)
- 当S[i] != T[j]时 dp[i][j] 会不变
- x是什么呢?,对于例子S=rabbb, T=rabb, x为2, 而dp[i-1][j-1] = 2, 而且其他的例子也能推出来,所以可以假设x = dp[i-1][j-1]
- 当计算dp[i][j]时, dp[i][j-1]是一定被包括进去的, 当两个字符串的最后一个字符相同时, 那么dp[i-1][j-1]也会包括进去
通过上面的分析, 我们已经找到了递推式子
dp[i][j] = dp[i][j-1] + (s[i] == t[j]) ? dp[i-1][j-1] : 0
而且通过上面的例子 可以找到初始情况
dp[0][j] = 0;
dp[j][0] = 1; (包含空串)
dp[0][0] = 1 (防止第一个条件覆盖)
AC代码
class Solution {
public:
int numDistinct(string s, string t) {
vector<vector<int> > dp(t.size() + 1, vector<int>(s.size() + 1, 0));
//初始化dp数组
dp[0][0] = 1;
for (int i = 1; i < s.size() + 1; ++i) {
dp[0][i] = 1;
}
for (int i = 1; i < t.size() + 1; ++i) {
dp[i][0] = 0;
}
//dp循环求解
for (int i = 1; i < t.size() + 1; ++i) {
for (int j = 1; j < s.size() + 1; ++j) {
dp[i][j] = dp[i][j - 1];
if (s[j - 1] == t[i - 1])
dp[i][j] += dp[i - 1][j - 1];
}
}
return dp[t.size()][s.size()];
}
};
LeetCode 115.不同的子序列 详解的更多相关文章
- Java实现 LeetCode 115 不同的子序列
115. 不同的子序列 给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数. 一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字 ...
- LeetCode.516 最长回文子序列 详解
题目详情 给定一个字符串s,找到其中最长的回文子序列.可以假设s的最大长度为1000. 示例 1: 输入: "bbbab" 输出: 4 一个可能的最长回文子序列为 "bb ...
- Leetcode 115.不同的子序列
不同的子序列 给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数. 一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串.(例 ...
- leetcode 115不同的子序列
滚动数组: /***** 下标从1开始 dp[i][j]:= numbers of subseq of S[1:j] equals T[1:i] if(s[j]==t[i]):(那么之后的子串可以是是 ...
- LeetCode 763划分字母区间 详解
题目详情 字符串 S 由小写字母组成.我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段.返回一个表示每个字符串片段的长度的列表. 示例 1: 输入: S = "ab ...
- LeetCode(42.接雨水)多解法详解
接雨水解法详解: 题目: 基本思路:从图上可以看出要想接住雨水,必须是凹字形的,也就是当前位置的左右两边必须存在高度大于它的地方,所以我们要想知道当前位置最多能存储多少水,只需找到左边最高处max_l ...
- [原创]mybatis详解说明
mybatis详解 2017-01-05MyBatis之代理开发模式1 mybatis-Dao的代理开发模式 Dao:数据访问对象 原来:定义dao接口,在定义dao的实现类 dao的代理开发模式 只 ...
- 3.awk数组详解及企业实战案例
awk数组详解及企业实战案例 3.打印数组: [root@nfs-server test]# awk 'BEGIN{array[1]="zhurui";array[2]=" ...
- linux查看端口及端口详解
今天现场查看了TCP端口的占用情况,如下图 红色部分是IP,现场那边问我是不是我的程序占用了tcp的链接,,我远程登陆现场查看了一下,这种类型的tcp链接占用了400多个,,后边查了一下资料,说E ...
随机推荐
- 通过代理模块拦截网页应用程序流量 - Intercept Web Application Traffic Using Proxy Modules
测试网站: http://testphp.vulnweb.com/login.php 浏览器代理设置为:127.0.0.1:8080 查看拦截流量: 方式1:通Proxy - Intercept 方式 ...
- Python 实现图像快速傅里叶变换和离散余弦变换
图像的正交变换在数字图像的处理与分析中起着很重要的作用,被广泛应用于图像增强.去噪.压缩编码等众多领域.本文手工实现了二维离散傅里叶变换和二维离散余弦变换算法,并在多个图像样本上进行测试,以探究二者的 ...
- Python学习周期 学习Python要多久?
学习python编程需要多长时间?首先我们需要明确一点,在互联网技术领域,技术始终在不断的迭代升级,只要进入IT行业就要时刻保持学习的状态,才能不被技术进步的车轮碾压.我们目前讨论的python学习周 ...
- 用windbg查看dmp文件,定位bug位置
windbg + .dmp + .pdb + 源代码,可以看到是哪个代码崩溃的 设置符号文件所在路径 File->Symbol File Path... 在输入框中填入.pdb文件所在的文件夹路 ...
- Java+MySQL企业级实训全套课程
总纲 JAVA基础部分 教学视频:第一讲:Java入门与环境搭建 提取码:h9vm第二讲:变量与运算符 提取码:928t第三讲:顺序结构及条件结构 提取码:3v1l第四讲:while ...
- 网络通信机制:Socket、TCP/IP、HTTP
13.1.1 TCP/IP协议 讲的很抽象,没具体看懂什么是TCP协议,什么是IP协议.IP协议保证消息从一个主机传送到另一个主机,消息在传送的过程中被分割成一个个小包,TCP协议会让两台相互连接的计 ...
- LVS+Keepalived 实现高可用负载均衡
前言 在业务量达到一定量的时候,往往单机的服务是会出现瓶颈的.此时最常见的方式就是通过负载均衡来进行横向扩展.其中我们最常用的软件就是 Nginx.通过其反向代理的能力能够轻松实现负载均衡,当有服务出 ...
- 比较两个等长的字符串,若相同,则输出Match!,若不同,则输出No Match!
文章目录 问题 代码 运行结果 问题 比较两个等长的字符串,若相同,则输出Match!,若不同,则输出No Match! 代码 data segment str1 db 'ASDFGHJKL';字符串 ...
- java实现经典坦克大战及源代码下载
坦克大战源码 (点击即可下载) 链接:https://pan.baidu.com/s/1m9aVheaquwxGKjYQrb72AA 提取码:j8dr see you ! 觉得有用的话点个赞再走
- Kylin Flink Cube 引擎的前世今生
Apache Kylin™ 是一个开源的.分布式的分析型数据仓库,提供 Hadoop/Spark 之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,它能在亚秒内查询巨大的表. Ky ...