代码随想录刷题第55天|Leetcode392判断子序列、Leetcode115不同的子序列

这篇具有很好参考价值的文章主要介绍了代码随想录刷题第55天|Leetcode392判断子序列、Leetcode115不同的子序列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、Leetcode392判断子序列

题目链接:392判断子序列

本题与1143最长公共子序列有一点不一样,最长公共子序列求两个字符串的最长公共子序列的长度,本题判断s是否为t的子序列。即t的长度是大于等于s的。

1、确定dp数组及下标含义

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

2、确定递推公式

if (s[i - 1] == t[j - 1]),那么dp[i][j] = dp[i - 1][j - 1] + 1;

if (s[i - 1] != t[j - 1]),此时相当于t要删除元素,dp[i][j] = dp[i][j - 1];

本题 如果删元素一定是字符串t,而 1143.最长公共子序列 是两个字符串都可以删元素。

3、初始化

全部初始化为0。

4、遍历顺序

从前向后,从上到下。

5、举例推导。

class Solution {
public:
    bool isSubsequence(string s, string t) {
        vector<vector<int>> dp(s.size() + 1, vector<int>(t.size()+1, 0));
        for (int i = 1; i <= s.size(); i++)
        {
            for (int j = 1; j <= t.size(); j++)
            {
                if (s[i - 1] == t[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
                else
                {
                    dp[i][j] = dp[i][j - 1];
                }
            }
        }

        if (dp[s.size()][t.size()] == s.size()) return true;
        else
        {
            return false;
        }
    }
};

2、Leetcode115不同的子序列

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

1、确定dp数组(dp table)以及下标的含义

dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。

2、确定递推公式

当s[i - 1] 与 t[j - 1]相等时,dp[i][j]可以有两部分组成。

一部分是用s[i - 1]来匹配,那么个数为dp[i - 1][j - 1]。

一部分是不用s[i - 1]来匹配,个数为dp[i - 1][j]。

例如: 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]来匹配,即:dp[i - 1][j];

3、初始化

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

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

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

4、遍历顺序

从dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j] 和 dp[i][j] = dp[i - 1][j]  可以看出 dp[i][j] 从左上方和正上方推出来,遍历的时候一定是从上到下,从左到右。

5、举例推导文章来源地址https://www.toymoban.com/news/detail-559275.html

class Solution {
public:
    int numDistinct(string s, string t) {
        vector<vector<uint64_t>> dp(s.size()+ 1 , vector<uint64_t>(t.size() + 1));
        for (int i = 0; i < s.size(); i++) dp[i][0] = 1;
        for (int j = 1; j < t.size(); j++) dp[0][j] = 0;

        for (int i = 1; i <= s.size(); i++)
        {
            for (int j = 1; j <= t.size(); 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[s.size()][t.size()];
    }
};

到了这里,关于代码随想录刷题第55天|Leetcode392判断子序列、Leetcode115不同的子序列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【代码随想录刷题记录】 392.判断子序列 、 115.不同的子序列

    1、题目 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,\\\"ace\\\"是\\\"abcde\\\"的一个子序列,而\\\"aec\\\"不是)。 题目链接:https://leetcode.cn/problems/is-subsequence/ 2、代码

    2024年02月16日
    浏览(45)
  • 代码随想录第五十七天|● 392.判断子序列 ● 115.不同的子序列

    题目: 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,\\\"ace\\\"是\\\"abcde\\\"的一个子序列,而\\\"aec\\\"不是)。 进阶: 如果有大量输入的 S,称作 S1, S2, … , Sk 其中

    2024年02月06日
    浏览(49)
  • 代码随想录第55天

    1.判断子序列: 动态规划五部曲分析如下: 确定dp数组(dp table)以及下标的含义 dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j] 。 注意这里是判断s是否为t的子序列。即t的长度是大于等于s的。 如果t的长度小于s那直接retur

    2024年02月08日
    浏览(31)
  • [自我记录]随想录刷题第二天 | 977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II

     代码随想录打卡第二天, 新手自我记录一下刷题历程, 仅为自我打卡使用. 今天刷了三道主题, 第一道双指针和第三道模拟做出来了, 第二道写出了暴力解法但是提交leetcode超时了, 测试用例过了18/20, 看了carl哥答案以后自己重新补写了滑动窗口方法. 977. 有序数组的平方 简单题

    2024年02月05日
    浏览(45)
  • 代码随想录:55. 跳跃游戏;45. 跳跃游戏 II

    给定一个非负整数数组  nums  ,你最初位于数组的  第一个下标  。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。 示例 1: 示例 2: 其实跳几步无所谓,关键在于可跳的覆盖范围! 不一定非要明确一次究竟跳几步,每次取最

    2023年04月11日
    浏览(48)
  • 代码随想录刷题

    704. 二分查找 27. 移除元素

    2024年01月25日
    浏览(51)
  • 【代码随想录】刷题Day47

    198. 打家劫舍 1.dp数组含义:dp[i]为i位置下的最大能得到的价值 2.根据条件:相邻不能偷。i位置的最大价值取决于i-1位置是否已经偷过了。如果偷过了,i位置的最大价值就是dp[i-1],即i位置的物品不偷;如果没有偷过,i位置的最大价值就是dp[i-2]+nuvms[i],i位置的数和对应的d

    2024年02月07日
    浏览(48)
  • 【代码随想录】刷题Day41

    343. 整数拆分 1.dp数组的含义:第i个就表示当前i能被拆分出相乘最大的整数 2.那么其实,所谓的后续的i对应的相乘最大整数其实就是前面的相乘最大整数拼凑而成,为了更好的区分我们将分离出来的数为j,那么我们的工作就是将一个又一个的j从i中剥离出,随后相乘即可。那

    2024年02月07日
    浏览(46)
  • 【代码随想录】刷题Day35

    860. 柠檬水找零 1.如果第一个顾客没有五元,那么直接返回false,因为店主开始没有零钱 2.定义两个int,一个记录5元,一个记录10元,随后遍历整个数组,会出现三种情况: 如果顾客给5元,直接num5加一 如果顾客给10元,判断num5是否大于0,大于则num5--,num10++;反之返回false

    2024年02月06日
    浏览(40)
  • 【代码随想录】刷题Day31

    455. 分发饼干 贪心的思路就是:小的饼干尽量去匹配胃口小的孩子,这样才能实现尽可能多孩子吃到。 那么代码就很好写了: 1.排序g和s,这样方便查找小的数 2.饼干的位置不停遍历,对应我们需要一个ret代表当前孩子位置 3.如果当前位置为孩子的数量,说明ret记录下所有的

    2024年02月06日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包