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
.
r | a | b | b | i | t | ||
1 | 0 | 0 | 0 | 0 | 0 | 0 | |
r | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
a | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
b | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
b | 1 | 1 | 1 | 2 | 1 | 0 | 0 |
b | 1 | 1 | 1 | 3 | 3 | 0 | 0 |
i | 1 | 1 | 1 | 3 | 3 | 3 | 0 |
t | 1 | 1 | 1 | 3 | 3 | 3 | 3 |
红字以上那些"0"是没有用的,不要去管它们。
这题的解题思路是动态规划。
1. 第一列,全部初始化我“1”,基于这样一个前提,任何一个string,空串都是它的一个子序列。
2. 从第二行开始,长度不要超过用来比较的S的子串的长度。例如,第二行,S = "r", 那么,T = "r'。第三行,S="ra",T="ra“。一直到第八行,S = "rabbbit",T="rabbit"。
3. 在每一个位置,如果当前位置上的字符相等,那么各不相同的子序列的个数至少是除去当前字符的子序列的个数,table[i][j] = table[i - 1] [j - 1]。如果它上一行的是有效的,able[i][j] += table[i - 1] [j]。
class Solution {
public:
int numDistinct(string S, string T) {
int slen = S.length(), tlen = T.length();
if (slen < tlen) {
return 0;
}
vector<vector<int> > table(slen + 1,vector<int>(tlen + 1));
for (int ii = 0; ii<= slen; ii ++) {
table[ii][0] = 1;
}
for (int ii = 1; ii <= slen; ii ++) {
for (int jj = 1; jj <= ii && jj <= tlen; jj ++) {
table[ii][jj] = S[ii - 1] == T[jj - 1] ? table[ii - 1][jj - 1] : 0;
table[ii][jj] += table[ii - 1][jj];
}
}
return table[slen][tlen];
}
};