Problem
Hint
DP
对于动态规划,我一直都是有些“望而生畏”的,不过人就是要这么迎难而上不是么,刺激!
这次利用的是二维数组的备忘录形式,令path[i][j]表示t[i]在s[j]中的匹配情况。
状态转移方程
path[i][j] = path[i][j-1]+t[i-1]==s[j-1]?path[i-1][j-1]:0;
如果能把状态方程转化为自己的语言,把所有的情况都能用文字表达出来,那么动态规划问题也就解决了一大半。
1)当i>j时,表示t的长度比s长,那么绝对不可能因s删除字符而成为t,所以这一部分(下半个矩阵都是0);
2)对于状态转移方程,表示当前t[i-1]如果和前面的s[j-1]相等的话,那么就可以去掉前面的s[j-1],产生新的情况。
Code
int numDistinct(char* s, char* t) {
int res = 0;
const int sLen = strlen(s);
const int tLen = strlen(t);
if(sLen<tLen || !tLen) return res;
int dp[tLen+1][sLen+1];
for(int i=0;i<=sLen;++i)
dp[0][i] = 1; //当t为空时唯一结果就是删除所有元素
for(int i=1;i<=tLen;++i){
for(int j=0;j<=sLen;++j){
if(j<i)
dp[i][j] = 0;
else
dp[i][j] = dp[i][j-1]+(t[i-1]==s[j-1]?dp[i-1][j-1]:0);
}
return dp[tLen][sLen];
}