原题:
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去掉i个字符,然后和T比较,为了节省时间,可以用一个哈希map来标志,<string,int>mymap,int代表string 能够表示字符串T的个数。但是超时了,为了这忘却的纪念,我决定把这个代码贴出来用来回忆。。。
超时代码():
class Solution {
public:
unordered_map<string,int> mymap;
int numDistinct(string S, string T) {
int result = 0;
if(mymap.find(S)!=mymap.end()) return mymap.find(S)->second;
if(S.length()<T.length()) {
mymap.insert({S,0});
return 0;
}
else if(S.length()==T.length()) {
if (S==T) result = 1;
else result = 0;
mymap.insert({S,result});
return result;
}
// test whether match if remove the ith element
for(int i = 0;i<S.length();i++){
string temp;
if(i>=1) temp = S.substr(0,i);
if(i<S.length()) temp.append(S.begin()+i+1,S.end());
result += numDistinct(temp,T);
}
mymap.insert({S,result});
return result;
}
};
其实我的这个方法主要是考虑的太多,所以超时,为了简化,其实应该是先从S里找和T第一个元素一样的元素(跟LCS很像,所以我的函数叫LCS),然后依次递归,因为在S中,可能有 多个元素和T中第一个相等,因此用一个for循环S里的所有字符,如果相等,则递归考虑之后的,并且,这所有的情况都加起来;
为了利用Dp,则利用一个数组来表示,record[i][j]表示S从i开始,T从j开始之后的字符串的所有情况。
如图:
代码如下(584ms):
class Solution {
public:
int numDistinct(string S, string T) {
vector<int>row(T.length(),-1);
vector<vector<int> > record (S.length(),row);
if(S.length()<T.length()) return 0;
return LCS(0,0,S,T,record);
}
int LCS(int indexS , int indexT , string &S , string &T , vector<vector<int>> &record ){
//if(indexT >= T.length() && indexT >= T.length()) return 1;
if(indexS >= S.length() || indexT >= T.length()) return 0;
if(record[indexS][indexT]!=-1)return record[indexS][indexT];
int result = 0;
for(int i = indexS ; i < S.length();i++){
if(S[i]==T[indexT] && indexT!=T.length()-1){
result += LCS(i+1 , indexT+1 , S , T , record);//+ LCS(i+1,indexT+1,S,T,record);
//break;
}
else if(S[i]==T[indexT] && indexT==T.length()-1){
//record[i][indexT] = 1;
result+=1;
//break;
}
}
record[indexS][indexT] = result;
return result;
}
};