首页 > 代码库 > 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 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串为S[0...lens-1],T串为T[0...lent-1],从S串尾部开始往前找第一个等于T[lent-1]的字符

假设S[i] == T[lent-1],这时原问题就分解为两个子问题,即在S[0...i-1]删除几个字符得到T[0...lent-1]及S[0...i-1]删除几个字符得到T[0...lent-2]

代码如下:

 

 1 class Solution { 2 public: 3     int numDistinct(string S, string T) { 4         return solve(S, S.length()-1, T, T.length()-1); 5     } 6      7     int solve(string& S, int is, string& T, int it) { 8         if( it < 0 ) return 1;  //当T成空串的时候,S必成空串,则T是S的distinct subsequence 9         if( is < 0 ) return 0;  //T不是空串,S先成空串,那么T就不是10         while( is >= 0 && S[is] != T[it] ) --is;    //S从后往前找等于T最后一个字符11         return solve(S, is-1, T, it) + solve(S, is-1, T, it-1); //原问题分解成两个子问题12     }13 };

方法二:上述递归方法求解是有很多子问题进行了重复求解,因此不能过大数据。那么可以将其转为dp问题,状态转移方程如下:

设dp[i][j]为S[0...i-1]删除字符得到T[0...j-1]的种数,那么

当S[i-1] == T[j-1]时,dp[i][j] = dp[i-1][j] + dp[i-1][j-1];

当S[i-1] != T[j-1]时,dp[i][j] = dp[i-1][j];

当 j == 0 时,dp[i][0] = 1;

代码如下:

 

 1 class Solution { 2 public: 3     int numDistinct(string S, string T) { 4         vector< vector<int> > dp( S.length()+1, vector<int>(T.length()+1, 0)); 5         for(int i=0; i<dp.size(); ++i) dp[i][0] = 1;    //当T为空串的时候,S删除字符得到T只有一种方法 6         for(int i=1; i<dp.size(); ++i) 7             for(int j=1; j<dp[i].size(); ++j) 8                 if( S[i-1] == T[j-1] ) dp[i][j] = dp[i-1][j] + dp[i-1][j-1];    //S[i-1] == T[j-1]的时候 9                 else dp[i][j] = dp[i-1][j]; //不等的时候10         return dp[S.length()][T.length()];11     }12 };

 

Distinct Subsequences