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
.
这又是一个动态规划问题,定义好状态转移方程就很好解决了。定义数组F[i][j]表示S的0~i子串和T的0~j子串的匹配程度。例如,S = "rabbbit"
, T = "rabbit"
很明显F[0][0]=1.我们找比较一般的位置,i=4,j=3位置,rabbb 可以匹配 rabb几个呢,答案是3个分别是rabb,rabb*,rab*b.
前一个在rabb和rabb已经匹配了,后面两个是rabb和rab匹配后加上rabbb和rabb最后一个字母匹配的结果。
rabb和rab匹配的结果是2,推理过程和上面一样。
于是有如下状态转移:
这里有两种情况,当S[i]==T[j] , F[i][j]=F[i-1][j]+F[i-1][j-1]。
当S[i]!=T[j]时,F[i][j]=F[i-1][j];
遍历所有位置,F[S.size()-1][T.size()-1] 就是所要求的结果了。
class Solution {
public:
int numDistinct(string S, string T) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(S.size()<T.size())
return 0;
int m=S.size(),n=T.size();
int f[m][n];
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
f[i][j]=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<=i&&j<n;j++)
{
if(T[j]==S[i])
{
if(!j)
{
if(!i)
f[0][0]=1;
else
f[i][0]=f[i-1][0]+1;
}
else
f[i][j]=f[i-1][j]+f[i-1][j-1];
}
else
{
if(i)
f[i][j]=f[i-1][j];
else
f[0][0]=0;
}
}
}
return f[m-1][n-1];
}
};
如果有不对的地方,欢迎大家指正。