48.115.不同的子序列

思路:

dp遍历是环环相扣,紧密相连的。

子数组、子串是连续的。子序列是不连续的。(看43、53两道题解里有说明)

递推公式和初始化有点不一样。

储备:

代码随想录

会把一些特殊的要求复制进来。方便检索。

问题重点:

1、题目要求:结果需要对 109 + 7 取模。
2、

例如: s:bagg 和 t:bag ,s[3] 和 t[2]是相同的,但是字符串s也可以不用s[3]来匹配,即用s[0]s[1]s[2]组成的bag。

当然也可以用s[3]来匹配,即:s[0]s[1]s[3]组成的bag。

所以当s[i - 1] 与 t[j - 1]相等时,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];

当s[i - 1] 与 t[j - 1]不相等时,dp[i][j]只有一部分组成,不用s[i - 1]来匹配(就是模拟在s中删除这个元素),即:dp[i - 1][j]

所以递推公式为:dp[i][j] = dp[i - 1][j];

dp[i][0]表示什么呢?

dp[i][0] 表示:以i-1为结尾的s可以随便删除元素,出现空字符串的个数。

那么dp[i][0]一定都是1,因为也就是把以i-1为结尾的s,删除所有元素,出现空字符串的个数就是1。

再来看dp[0][j],dp[0][j]:空字符串s可以随便删除元素,出现以j-1为结尾的字符串t的个数。

那么dp[0][j]一定都是0,s如论如何也变成不了t。

最后就要看一个特殊位置了,即:dp[0][0] 应该是多少。

dp[0][0]应该是1,空字符串s,可以删除0个元素,变成空字符串t。

最后:

class Solution {
public:
    int numDistinct(string s, string t) {
        int n=s.size();
        int m=t.size();
        vector<vector<unsigned int>> dp(n+1,vector<unsigned int>(m+1,0));
        //母串以i-1结尾,子串以j-1结尾,的子序列最大个数
        for (int i=0;i<n;i++) dp[i][0]=1;//子串是空串。母串都是1
        for (int j=1;j<m;j++) dp[0][m]=0;//母串是空串,故无论多少都是0
        //从第一个开始比对
        for (int i=1;i<=n;i++) {
            for (int j=1;j<=m;j++) {
                if (s[i-1]==t[j-1]) dp[i][j]=dp[i-1][j-1]+dp[i-1][j];//连续两个相同的话,可以用上一层循环的
                else dp[i][j]=dp[i-1][j];//沿用上一层循环的
            }
        }
        return dp[n][m];
    }
};

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值