问题:
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
.
这道题说得让人不太容易读懂。它的意思是:T作为一个整体,S有多少个subsequences时T。
用的方法是DP:table[i][j]表示当S是0到 i 的substr的时候、T是0到 j 的substr的时候,有多少个。那么怎么得到table[i][j]呢?我们看S[i]和T[j] 是不是相等。如果是,则两个string的最后一个字符match,所以table[i-1][j-1]。但就算两个string的最后一个字符match,也不代表就一定要匹配它们的最后一个字符。所以还要加上table[i-1][j]。所以有了如下代码:
class Solution {
public:
int numDistinct(string S, string T) {
vector<vector<int> > table (S.size() + 1, vector<int> (T.size() + 1, 0));
for (int i = 0; i <= S.size(); i ++)
table[i][0] = 1;
for (int i = 1; i <= S.size(); i ++) {
for (int j = 1; j <= T.size(); j ++) {
table[i][j] = table[i-1][j] + (S[i - 1] == T[j - 1]) * table[i-1][j-1];
}
}
return table[S.size()][T.size()];
}
};
但这并不是最优代码:我们在空间上还可以更节省一点。我们可以不用二维的table,而用一维的。
代码:
class Solution {
public:
int numDistinct(string S, string T) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int record[200];
for(int i=1; i<200; i++)
record[i]=0;
record[0]=1;
for(int i=1; i<=S.size(); i++)
for(int j=T.size(); j>=1; j--)
{
if(S[i-1]==T[j-1])
record[j]+=record[j-1];
}
return record[T.size()];
}
};