115.Distinct Subsequences

思路:动态规划。注意题目默认的是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;
    }


};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值