https://oj.leetcode.com/problems/distinct-subsequences/
对于string S 和 T求,T 是 S的几种子串。
首先想到了递归方法,列出递归公式,奈何超时了:
如果S[sBegin] == T[tBegin] 则是 numSubDistinct(sBegin+1,tBegin+1,S,T) + numSubDistinct(sBegin+1,tBegin,S,T);
如果不等于,则 numSubDistinct(sBegin+1,tBegin,S,T);
如果T的遍历指针到头了,则说明成功了一次匹配
class Solution { public: int numDistinct(string S, string T) { int ans = 0; if(S.size()<T.size()) return 0; if(S.size() == T.size()) if(S == T) return 1; else return 0; return numSubDistinct(0,0,S,T); } int numSubDistinct(int sBegin,int tBegin,string &S,string &T) { if(tBegin== T.size()) return 1; if(sBegin == S.size() && tBegin!= T.size()) return 0; if(S[sBegin] == T[tBegin]) return numSubDistinct(sBegin+1,tBegin+1,S,T) + numSubDistinct(sBegin+1,tBegin,S,T); else return numSubDistinct(sBegin+1,tBegin,S,T); } };
之后,考虑用递推实现。
根据思路来说,首先想到从后往前递推,但如果从后往前可以,则从前往后也可以。
建立二维数组num[S.size()][T.size()]存这个过程中产生的中间结果。
首先定义:num[i][j]是对于S从0到 i 的子串,对于T从 0 到 j 的子串,这两个字符串,T是S的子串数。
如果S[sBegin] == T[tBegin] num[sBegin][tBegin] = num[sBegin-1][tBegin-1] + num[sBegin-1][tBegin];
如果不等于则 num[sBegin][tBegin] = num[sBegin-1][tBegin];
根据公式,考虑到进行两层循环,
但是循环之前需要初始化
class Solution { public: int numDistinct(string S, string T) { int ans = 0; if(S.size()<T.size()) return 0; if(S.size() == T.size()) if(S == T) return 1; else return 0; vector<vector<int> > num; num.resize(S.size()); for(int i = 0;i<S.size();i++) num[i].resize(T.size()); //initialize if(S[0] == T[0]) num[0][0] = 1; else num[0][0] = 0; for(int i = 1;i<S.size();i++) { if(S[i] == T[0]) num[i][0] = num[i-1][0] + 1; else num[i][0] = num[i-1][0]; } for(int j = 1;j<T.size();j++) { num[0][j] = 0; } for(int sBegin = 1;sBegin<S.size();sBegin++) for(int tBegin = 1;tBegin<T.size();tBegin++) { if(S[sBegin] == T[tBegin]) num[sBegin][tBegin] = num[sBegin-1][tBegin-1] + num[sBegin-1][tBegin]; else num[sBegin][tBegin] = num[sBegin-1][tBegin]; } return num[S.size()-1][T.size()-1]; } };