Given a string S and a string T, count the number of distinct subsequences of S which equals T.

A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).

Example 1:

Input: S = "rabbbit", T = "rabbit"
Output: 3
Explanation: As shown below, there are 3 ways you can generate "rabbit" from S.
(The caret symbol ^ means the chosen letters) rabbbit
^^^^ ^^
rabbbit
^^ ^^^^
rabbbit
^^^ ^^^

Example 2:

Input: S = "babgbag", T = "bag"
Output: 5
Explanation: As shown below, there are 5 ways you can generate "bag" from S.
(The caret symbol ^ means the chosen letters) babgbag
^^ ^
babgbag
^^ ^
babgbag
^ ^^
babgbag
^ ^^
babgbag
^^^

看到有关字符串的子序列或者配准类的问题,首先应该考虑的就是用动态规划 Dynamic Programming 来求解,这个应成为条件反射。而所有 DP 问题的核心就是找出状态转移方程,想这道题就是递推一个二维的 dp 数组,其中 dp[i][j] 表示s中范围是 [0, i] 的子串中能组成t中范围是 [0, j] 的子串的子序列的个数。下面我们从题目中给的例子来分析,这个二维 dp 数组应为:

  Ø r a b b b i t
Ø 1 1 1 1 1 1 1 1
r 1 1
a 1 1
b 0 1 2
b 1 3
i 0 3
t 0 3

首先,若原字符串和子序列都为空时,返回1,因为空串也是空串的一个子序列。若原字符串不为空,而子序列为空,也返回1,因为空串也是任意字符串的一个子序列。而当原字符串为空,子序列不为空时,返回0,因为非空字符串不能当空字符串的子序列。理清这些,二维数组 dp 的边缘便可以初始化了,下面只要找出状态转移方程,就可以更新整个 dp 数组了。我们通过观察上面的二维数组可以发现,当更新到 dp[i][j] 时,dp[i][j] >= dp[i][j - 1] 总是成立,再进一步观察发现,当 T[i - 1] == S[j - 1] 时,dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1],若不等, dp[i][j] = dp[i][j - 1],所以,综合以上,递推式为:

dp[i][j] = dp[i][j - 1] + (T[i - 1] == S[j - 1] ? dp[i - 1][j - 1] : 0)

根据以上分析,可以写出代码如下:

class Solution {
public:
int numDistinct(string s, string t) {
int m = s.size(), n = t.size();
vector<vector<long>> dp(n + , vector<long>(m + ));
for (int j = ; j <= m; ++j) dp[][j] = ;
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
dp[i][j] = dp[i][j - ] + (t[i - ] == s[j - ] ? dp[i - ][j - ] : );
}
}
return dp[n][m];
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/115

参考资料:

https://leetcode.com/problems/distinct-subsequences/

https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java

https://leetcode.com/problems/distinct-subsequences/discuss/37412/Any-better-solution-that-takes-less-than-O(n2)-space-while-in-O(n2)-time

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 115. Distinct Subsequences 不同的子序列的更多相关文章

  1. [leetcode]115. Distinct Subsequences 计算不同子序列个数

    Given a string S and a string T, count the number of distinct subsequences of S which equals T. A su ...

  2. Java for LeetCode 115 Distinct Subsequences【HARD】

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  3. Leetcode 115 Distinct Subsequences 解题报告

    Distinct Subsequences Total Accepted: 38466 Total Submissions: 143567My Submissions Question Solutio ...

  4. leetcode 115 Distinct Subsequences ----- java

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  5. Leetcode#115 Distinct Subsequences

    原题地址 转化为求非重路径数问题,用动态规划求解,这种方法还挺常见的 举个例子,S="aabb",T="ab".构造如下地图("."表示空位 ...

  6. [LeetCode] Distinct Subsequences 不同的子序列

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  7. 【LeetCode】115. Distinct Subsequences 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...

  8. 【一天一道LeetCode】#115. Distinct Subsequences

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  9. 115. Distinct Subsequences

    题目: Given a string S and a string T, count the number of distinct subsequences of T in S. A subseque ...

随机推荐

  1. LinkedHashMap实现和LRU

    HashMap是Java中叫法,在Python中就叫Dict 在Python的标准库中实现了LinkedHashMap,它的名字叫OrderedDict,它的源码比较简单,OrderedDict继承了 ...

  2. Docker 镜像-管理-导入-导出

    目录 Docker 镜像基本概念 Docker 镜像加速 Docker 镜像 常用命令 Docker 镜像的创建和导出导入 Docker 镜像基本概念 我们使用的容器都是基于镜像的,镜像是由多层组成的 ...

  3. Java自学-I/O 控制台输入流System.in

    Java 控制台输入流 System.in和Scanner System.out 是常用的在控制台输出数据的 System.in 可以从控制台输入数据 步骤 1 : System.in package ...

  4. addEventListener和JavaScript的事件机制

    JavaScript的事件处理分为两个阶段: 捕获阶段:从根节点向event.target层层传递 冒泡阶段:从event.target向根节点层层传递 addEventListener(eventN ...

  5. 英语LIGNALOO沉香lignaloo单词

    沉香lignaloo,是瑞香科.沉香属的一种乔木,高5-15米.树皮暗灰色,几平滑,纤维坚韧:小枝圆柱形,具绉纹,幼时被疏柔毛,后逐渐脱落,无毛或近无毛.产于中国广东.海南.广西.福建等地.喜生于低海 ...

  6. Docker 网络简单说明

    docker0 网络模型小结 Docker Daemon 会创建出一个名为 docker0 的虚拟网桥 ,用来连接宿主机与容器,或者连接不同的容器. veth pair 是用于不同network na ...

  7. java基础类型的byte为长度

    java基础类型的字节长度: 类型 byte数/位数 最大/最小值 byte 1/8 127/-128 short 2/16 32767/-32768 int 4/32 2147483647/-214 ...

  8. python处理孤立的异常点

    假设有一个列表,a = [61, 40, 70, 80, 86, 50, 88, 33, 76, 64],保存的是设备的状态值随时间的变化,超过60即为异常,但是对于孤立的异常点,我们需要将其忽略,只 ...

  9. Jenkins + Pipeline + Git + Maven (十)

    一.准备环境介绍 192.168.5.71 # gitlab 仓库IP 192.168.5.72 # 开发环境,用于提交代码等 192.168.5.73 # tomcat 部署solo服务站点 192 ...

  10. python3 AES 加解密

    #coding:utf-8 import base64 from Crypto.Cipher import AES #注:python3 安装 Crypto 是 pip3 install -i htt ...