[LeetCode] 115. 不同的子序列(动态规划)

115. 不同的子序列(动态规划)

给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数。

一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,“ACE” 是 “ABCDE” 的一个子序列,而 “AEC” 不是)

题目数据保证答案符合 32 位带符号整数范围。

在这里插入图片描述

解题思路: 观察此题属于求子序列的问题,联想到用DP解题,然后定义dp[i][j]表示字符串s前j个字符中包含字符串t前i个字符的个数,但是到这儿就断片儿了,参考了一下grandyang大神的思路,发现通过列举找出了状态转移方程,按照这个思路解完题后,想了想,如果不通过列举,可不可以这么找到状态转移方程,一般来说,想找出状态转移方程我们需要先列出上一个状态有哪些,然后当前状态与上一个状态的关联是什么,另外一点是,在分解上一个状态时,要找一个标准,使得分解的状态互斥、完备,OK,我们相信上一个状态是不是可以分解为[i-1,j],[i,j-1],[i-1][j-1],(t->s),但是对于状态[i,j-1]是不需要且不成立的,因为s先增长,t后增长才有意义,那剩下的就是状态[i-1,j]和状态[i-1][j-1],对于状态[i-1][j-1]要求s[j]==st[i]才能对状态[i][j]有贡献,OK,至此,即可分析出状态转移方程~

// dp[i][j] = dp[i][j - 1] + (T[i - 1] == S[j - 1] ? dp[i - 1][j - 1] : 0)
class Solution {
public:
    int numDistinct(string s, string t) {
        int m = t.size(), n = s.size();
        vector<vector<long>> dp(m + 1, vector<long>(n + 1, 0));
        for (int j = 0; j <= n; ++j)  dp[0][j] = 1;
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                dp[i][j] = dp[i][j - 1] + (t[i - 1] == s[j - 1] ? dp[i - 1][j - 1] : 0);
            }
        }
        return dp[m][n];
    }
};

————————————

参考资料:

https://www.cnblogs.com/grandyang/p/4294105.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值