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

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代码:

 1 public int numDistinct(String S, String T) {
 2   // Start typing your Java solution below
 3   // DO NOT write main() function
 4   if (S.length() == 0) {
 5     return T.length() == 0 ? 1 : 0;
 6   }
 7   if (T.length() == 0) {
 8     return 1;
 9   }
10   int cnt = 0;
11   for (int i = 0; i < S.length(); i++) {
12     if (S.charAt(i) == T.charAt(0)) {
13       cnt += numDistinct(S.substring(i + 1), T.substring(1));
14     }
15   }
16   return cnt;
17 }  

遇到这种两个串的问题,很容易想到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()

 1 class Solution {
 2 public:
 3     int numDistinct(string S, string T) {
 4         if(S.empty()||T.empty()) return 0;
 5         if(S.length()<T.length()) return 0;
 6         int dp[T.length()+1][S.length()+1];
 7         dp[0][0]=1;
 8         for(int i=1;i<=T.length();i++){
 9             dp[i][0]=0;
10         }
11         for(int j=1;j<=S.length();j++){
12             dp[0][j]=1;
13         }
14         for(int i=1;i<=T.length();i++){
15             for(int j=1;j<=S.length();j++){
16                 dp[i][j]=dp[i][j-1];
17                 if(T[i-1]==S[j-1])
18                     dp[i][j]+=dp[i-1][j-1];
19             }
20         }
21         return dp[T.length()][S.length()];
22     }
23 };
时间: 2024-11-10 01:23:13

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

uva10069 - Distinct Subsequences(大数+DP)

题目:uva10069 - Distinct Subsequences(大数+DP) 题目大意:给出字符串A , B.问能够在A中找到多少子串B,可以不连续. 解题思路:dp[i][j] 代表从i位开始的B串在从j位开始的A串中能够找到多少种. B[i] == A[j] dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1]: B[i] != A[j] dp[i][j] = dp[i][j - 1]:边界要处理一下.就是B中只有最后的那个字符来和A匹配的情况要处理一

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

在论坛中看到一个帖子,帖子中有一些sql方面的面试题,我觉得这些面试题很有代表性. 原帖的连接为:http://bbs.csdn.net/topics/390884161?page=1#post-398177057 下面是我的解法,供大家参考: 1.分拆字符串 create table test1 (number varchar(100)) insert into test1 values ('1,2,3,4,5,6') 希望结果: number ------ 1 2 3 4 5 6 (6 行受

[LeetCode] Distinct Subsequences 不同的子序列

Given a string S and a string T, count the number of distinct subsequences of T in S. 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

[LeetCode] Count Different Palindromic Subsequences 计数不同的回文子序列的个数

Given a string S, find the number of different non-empty palindromic subsequences in S, and return that number modulo 10^9 + 7. A subsequence of a string S is obtained by deleting 0 or more characters from S. A sequence is palindromic if it is equal

CSU 1354 Distinct Subsequences 求不相同子序列的和 dp

题目链接:点击打开链接 Description Give a positive number, count the sum of the distinct subsequence of it, moreover, any subsequence should not contain leading zeroes except it is zero. For example, if the number is 1022, the answer is 1 + 0 + 2 + 10 + 12 + 22

不同的子序列 &#183; Distinct Subsequences

[抄题]: 给出字符串S和字符串T,计算S的不同的子序列中T出现的个数. 子序列字符串是原始字符串通过删除一些(或零个)产生的一个新的字符串,并且对剩下的字符的相对位置没有影响.(比如,"ACE"是"ABCDE"的子序列字符串,而"AEC"不是). Here is an example:S = "rabbbit", T = "rabbit" Return 3. [思维问题]: [一句话思路]: 由于要查找T

115. Distinct Subsequences *HARD* -- 字符串不连续匹配

Given a string S and a string T, count the number of distinct subsequences of T in S. 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

[LeetCode] Distinct Subsequences 解题思路

Given a string S and a string T, count the number of distinct subsequences of T in S. 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

LeetCode: Distinct Subsequences 解题报告

Distinct Subsequences Given a string S and a string T, count the number of distinct subsequences of T in S. 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 di