代码随想录算法训练营第五十四天| 392.判断子序列,115.不同的子序列

目录

题目链接: 392.判断子序列

思路

代码

题目链接: 115.不同的子序列

思路

代码

总结


题目链接:392.判断子序列

思路

        ①dp数组,dp[i][j]表示下标为i-1结尾的字符串s和下标j-1结尾的字符串t,相同子序列的长度为dp[i][j]

        ②递推公式,当上一个字符相等时,dp[i][j] = dp[i-1][j-1] + 1,否则dp[i][j] = dp[i][j-1],不相等时说明s的当前字符未在t中找到,跳过t的当前字符,与t的下一个字符相比较

        ③dp数组初始化,根据递推公式,dp[0][0] = 0,dp[i][0] = 0,递推公式后的值都要由其进行递推,初始化为0是因为母串t为空串时,公共长度也为0

        ④遍历顺序,先子串s,后母串t,从前往后

        ⑤推导dp数组

代码

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int slen = s.size();
        int tlen = t.size();
        vector<vector<int>> dp(slen + 1, vector<int>(tlen + 1, 0));
        // 终止条件是小于等于,因为字符串的索引是i-1和j-1
        for (int i = 1; i <= slen; i++) {
            for (int j = 1; j <= tlen; j++) {
                // 相等时,长度加一
                if (s[i - 1] == t[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }
                // 不等时,遍历母串t的下一个位置
                else {
                    dp[i][j] = dp[i][j - 1];
                }
            }
        }
        // dp数组右下角的值等于子串长度时说明s是t的子序列
        if (dp[slen][tlen] == slen)
            return true;
        return false;
    }
};

题目链接:115.不同的子序列

思路

        ①dp数组,dp[i][j]表示下标以i-1的s在下标以j-1的t中出现的次数为dp[i][j]

        ②递推公式,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] = dp[i-1][j]

        ③dp数组初始化,dp[i][0] = 1;dp[0][j] = 0,t为空,空字符肯定在s中出现一次;s为空,则出现次数肯定为0

        ④遍历顺序,从左到右,从上到下

        ⑤推导dp数组

代码

class Solution {
public:
    int numDistinct(string s, string t) {
        int slen = s.size(); // 母串长度
        int tlen = t.size(); // 子串长度
        vector<vector<uint64_t>> dp(slen + 1, vector<uint64_t>(tlen + 1, 0));
        for (int i = 0; i < slen; i++) {
            dp[i][0] = 1;
        }
        for (int i = 1; i <= slen; i++) {
            for (int j = 1; j <= tlen; 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[slen][tlen];
    }
};

总结

        ①子序列问题都是从当前字符相等和不相等两种情况进行讨论,392.判断子序列,相等时长度加一,不等时母串跳过当前元素;115.不同的子序列是连续判断,因此在相等时要考虑匹配当前元素和不匹配当前元素两种情况,不等时也是跳过当前元素

        ②搞清楚dp数组含义,在初始化时根据递推公式以及dp数组含义进行初始化,这点尤为重要

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值