思路:动态规划。注意题目默认的是s的长度大于等于t的长度。
状态划分:nums[i][j]表示s[0...i]和t[0...j]符合Distinct Subsequences要求的个数。
递推式: 如果s[i]和t[j]相同,那么有两种情况,一种是取s[i],那么就得看s[0~i-1]和t[0~j-1]的个数;一种是舍弃s[i],那么就得看s[0~i-1]和t[0~j]的个数,因此递推式是nums[i][j]=nums[i-1][j-1]+nums[i-1][j];如果s[i]和t[j]不同,那么递推式就是nums[i][j]=nums[i-1][j]。
初始化:求出s[0~len_s][0]的值;另外所有s[i][i+1~len_t]都必须为0
class Solution {
public:int numDistinct(string s, string t) {
int len_s=s.size();
int len_t=t.size();
//题目理解1:默认s长度大于t
if(len_s<len_t) return 0;
if(len_t==0) return 1;
//题目理解2:s长度可以小于t,后面发现题目并不是这个意思
//if(len_s==0 || len_t==0) return 0;
//if(len_s<len_t) return numDistinct(t,s);
//申请动态内存,nums[i][j]表示s[0...i]和t[0...j]符合Distinct Subsequences要求的个数
int **nums=new int*[len_s];
for(int i=0;i<len_s;++i){
nums[i]=new int[len_t];
}
//初始化
for(int i=0;i<len_s;++i){
for(int j=0;j<len_t;++j){
nums[i][j]=0;
}
}
int tem_nums=0;
for(int i=0;i<len_s;++i){
if(s[i]==t[0])
nums[i][0]=(++tem_nums);
else
nums[i][0]=tem_nums;
}
//process:如果s[i]和t[j]相同,那么有两种情况,一种是取s[i],那么就得看s[0~i-1]和t[0~j-1]的个数;一种是舍弃s[i],那么就得看s[0~i-1]和t[0~j]的个数,因此递推式是nums[i][j]=nums[i-1][j-1]+nums[i-1][j];如果s[i]和t[j]不同,那么递推式就是nums[i][j]=nums[i-1][j]。
for(int i=1;i<len_s;++i){
for(int j=1;j<=min(i,len_t-1);++j){
if(s[i]==t[j]){
nums[i][j]=nums[i-1][j-1]+nums[i-1][j];
}else{
nums[i][j]=nums[i-1][j];
}
}
}
//result
int result=nums[len_s-1][len_t-1];
for(int i=0;i<len_s;++i){
delete []nums[i];
}
delete []nums;
return result;
}
};