Given a string S and a string T, count the number of distinct subsequences ofT inS.

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).

Here is an example:
S = "rabbbit"T = "rabbit"

Return 3.

简单翻译一下,给定两个字符串S和T,求S有多少个不同的子串与T相同。S的子串定义为在S中任意去掉0个或者多个字符形成的串。

递归求解:

首先找到在S中与T的第一个字符相同的字符,从这个字符开始,递归地求S和T剩下的串。T为空串时,返回1。因为空串本身是另外一个串的一个子序列。这个算法实现简单,但是果然不出意料,大集合超时。

Java代码:

 public int numDistinct(String S, String T) {
// Start typing your Java solution below
// DO NOT write main() function
if (S.length() == 0) {
return T.length() == 0 ? 1 : 0;
}
if (T.length() == 0) {
return 1;
}
int cnt = 0;
for (int i = 0; i < S.length(); i++) {
if (S.charAt(i) == T.charAt(0)) {
cnt += numDistinct(S.substring(i + 1), T.substring(1));
}
}
return cnt;
}

遇到这种两个串的问题,很容易想到DP。但是这道题的递推关系不明显。可以先尝试做一个二维的表int[][] dp,用来记录匹配子序列的个数(以S ="rabbbit",T = "rabbit"为例):

r a b b b i t

1 1 1 1 1 1 1 1

0 1 1 1 1 1 1 1

a 0 1 1 1 1 1 1

b 0 0 2 3 3 3

b 0 0 0 0 3 3 3

i 0 0 0 0 0 0 3 3

t 0 0 0 0 0 0 0 3

从这个表可以看出,无论T的字符与S的字符是否匹配,dp[i][j] = dp[i][j - 1].就是说,假设S已经匹配了j - 1个字符,得到匹配个数为dp[i][j - 1](即若S[j]!=T[i],则该出现次数等于T[0-i]在S[0-(j-1)]出现的次数).现在无论S[j]是不是和T[i]匹配,匹配的个数至少是dp[i][j - 1]。除此之外,当S[j]和T[i]相等时,我们可以让S[j]和T[i]匹配,然后让S[j - 1]和T[i - 1]去匹配(T[0-(i-1)]在S[0-(j-1)]出现的次数*(T[i]==S[j])=1)
所以递推关系为:

dp[0][0] = 1; // T和S都是空串.

dp[0][1 ... S.length() - 1] = 1; // T是空串,S只有一种子序列匹配。

dp[1 ... T.length() - 1][0] = 0; // S是空串,T不是空串,S没有子序列匹配。

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

 class Solution {
public:
int numDistinct(string S, string T) {
if(S.empty()||T.empty()) return ;
if(S.length()<T.length()) return ;
int dp[T.length()+][S.length()+];
dp[][]=;
for(int i=;i<=T.length();i++){
dp[i][]=;
}
for(int j=;j<=S.length();j++){
dp[][j]=;
}
for(int i=;i<=T.length();i++){
for(int j=;j<=S.length();j++){
dp[i][j]=dp[i][j-];
if(T[i-]==S[j-])
dp[i][j]+=dp[i-][j-];
}
}
return dp[T.length()][S.length()];
}
};

Distinct Subsequences(不同子序列的个数)——b字符串在a字符串中出现的次数、动态规划的更多相关文章

  1. java程序员的从0到1:统计某字符串在某文件中出现的次数(面试题)

    目录: 1. 编程题目 2. 方法一 3. 方法二 4. 方法三 5. 方法四 6. 总结 正文: 1. 编程题目 写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数. 2. ...

  2. 子序列 sub sequence问题,例:最长公共子序列,[LeetCode] Distinct Subsequences(求子序列个数)

    引言 子序列和子字符串或者连续子集的不同之处在于,子序列不需要是原序列上连续的值. 对于子序列的题目,大多数需要用到DP的思想,因此,状态转移是关键. 这里摘录两个常见子序列问题及其解法. 例题1, ...

  3. [Leetcode] distinct subsequences 不同子序列

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

  4. 115 Distinct Subsequences 不同子序列

    给定一个字符串 S 和一个字符串 T,求 S 的不同的子序列中 T 出现的个数.一个字符串的一个子序列是指:通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串.(譬如," ...

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

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

  6. [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 ...

  7. 在论坛中出现的比较难的sql问题:27(字符串拆分、字符串合并、非连续数字的间隔范围、随机返回字符串)

    原文:在论坛中出现的比较难的sql问题:27(字符串拆分.字符串合并.非连续数字的间隔范围.随机返回字符串) 在论坛中看到一个帖子,帖子中有一些sql方面的面试题,我觉得这些面试题很有代表性. 原帖的 ...

  8. [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 ...

  9. [Swift]LeetCode115. 不同的子序列 | Distinct Subsequences

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

随机推荐

  1. Leetcode 448.找到所有数组中消失的数字

    找到所有数组中消失的数字 给定一个范围在  1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次. 找到所有在 [1, n] 范围之间没有出现 ...

  2. PDO PDO_MYSQL MYSQLI MYSQL 的区别

    MYSQL,MYSQLI 这两个扩展本身就是访问MYSQL数据库的驱动 PDO则是一个抽象层接口 向程序员提供可调用的API是由,MYSQL驱动.MYSQLI驱动,以及PDO来提供. PDO_MYSQ ...

  3. git命令综合

    Git 是一个很强大的分布式版本控制系统.它不但适用于管理大型开源软件的源代码,管理私人的文档和源代码也有很多优势.Git常用操作命令:1) 远程仓库相关命令检出仓库:$ git clone git: ...

  4. hive查询语法

    1.创建表: >create table value_data(citing INT,cited INT) >row format delimited >fields termina ...

  5. 【Luogu】P3709大爷的字符串题(莫队算法)

    题目链接 语文题啊…… 看题解发现是让求区间中最多的数的个数,于是果断理解了一会题解……莫队套上完事. sum[i]表示i这个数出现的次数,cnt[i]表示出现i次的数有几个,然后乱搞搞……就好了 # ...

  6. APUE 学习笔记(三) 文件和目录

    1. 文件类型 文件类型信息包含在 struct stat 里的 st_mode 成员 (1)普通文件,unix内核并不区分文本文件和二进制文件 (2)目录文件,这种文件包含了其他文件的名字以及指向这 ...

  7. FOJ Problem 2256 迷宫

                                                                                                        ...

  8. 【HDOJ5974】A Simple Math Problem(构造,解方程)

    题意:给定A与B,要求构造出一组X,Y,使得X+Y=A,lcm(X,Y)=B A<=2e4,B<=1e9 思路:A的范围较小,考虑以A为突破口 枚举A的约数k,复杂度O(sqrt(A)) ...

  9. 相关分析 BZOJ 4821

    相关分析 [问题描述] Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等.Frank不仅喜欢观测,还喜欢分析观测到的数据.他 ...

  10. linux内核学习之四:进程切换简述【转】

    转自:http://www.cnblogs.com/xiongyuanxiong/p/3531884.html 在讲述专业知识前,先讲讲我学习linux内核使用的入门书籍:<深入理解linux内 ...