力扣刷题记录 (七)动态规划(五)子序列系列

2023-11-03

① 题号300.最长递增子序列
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例 1: 输入:nums = [10,9,2,5,3,7,101,18] 输出:4 解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2: 输入:nums = [0,1,0,3,2,3] 输出:4
示例 3: 输入:nums = [7,7,7,7,7,7,7] 输出:1

提示:
1 <= nums.length <= 2500
-10^4 <= nums[i] <= 104

解析:
最长上升子序列是动规的经典题目,这里dp[i]是可以根据dp[j] (j < i)推导出来的,那么依然用动规五部曲来分析详细一波。
1.

答:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
② 题号674. 最长连续递增序列
给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], …, nums[r - 1], nums[r]] 就是连续递增子序列。
示例 1: 输入:nums = [1,3,5,4,7] 输出:3 解释:最长连续递增序列是 [1,3,5], 长度为3。 尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。
示例 2: 输入:nums = [2,2,2,2,2] 输出:1 解释:最长连续递增序列是 [2], 长度为1。
提示:
0 <= nums.length <= 10^4
-10^9 <= nums[i] <= 10^9

解析:
本题相对于300.最长递增子序列最大的区别在于“连续”。
本题要求的是最长连续递增序列。
动规五部曲分析如下:
1.确定dp数组(dp table)以及下标的含义
dp[i]:以下标i为结尾的数组的连续递增的子序列长度为dp[i]。
注意这里的定义,一定是以下标i为结尾,并不是说一定以下标0为起始位置。
2.确定递推公式
如果 nums[i + 1] > nums[i],那么以 i+1 为结尾的数组的连续递增的子序列长度 一定等于 以i为结尾的数组的连续递增的子序列长度 + 1 。
即:dp[i + 1] = dp[i] + 1;
注意这里就体现出和动态规划:300.最长递增子序列的区别!
因为本题要求连续递增子序列,所以就必要比较nums[i + 1]与nums[i],而不用去比较nums[j]与nums[i] (j是在0到i之间遍历)。
既然不用j了,那么也不用两层for循环,本题一层for循环就行,比较nums[i + 1] 和 nums[i]。
这里大家要好好体会一下!
3.dp数组如何初始化
以下标i为结尾的数组的连续递增的子序列长度最少也应该是1,即就是nums[i]这一个元素。
所以dp[i]应该初始1;
4.确定遍历顺序
从递推公式上可以看出, dp[i + 1]依赖dp[i],所以一定是从前向后遍历。
本文在确定递推公式的时候也说明了为什么本题只需要一层for循环,代码如下:
在这里插入图片描述
5.举例推导dp数组
已输入nums = [1,3,5,4,7]为例,dp数组状态如下:
在这里插入图片描述

答:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
③ 题号718. 最长重复子数组
给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
示例:
输入: A: [1,2,3,2,1] B: [3,2,1,4,7] 输出:3 解释: 长度最长的公共子数组是 [3, 2, 1] 。
提示:
1 <= len(A), len(B) <= 1000
0 <= A[i], B[i] < 100

解析:

答:
在这里插入图片描述
在这里插入图片描述
④ 题号1143.最长公共子序列
给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。
若这两个字符串没有公共子序列,则返回 0。

示例 1:
输入:text1 = “abcde”, text2 = “ace”
输出:3
解释:最长公共子序列是 “ace”,它的长度为 3。

示例 2:
输入:text1 = “abc”, text2 = “abc”
输出:3
解释:最长公共子序列是 “abc”,它的长度为 3。

示例 3:
输入:text1 = “abc”, text2 = “def”
输出:0
解释:两个字符串没有公共子序列,返回 0。

提示:
1 <= text1.length <= 1000
1 <= text2.length <= 1000 输入的字符串只含有小写英文字符。

解析:

答:
在这里插入图片描述
在这里插入图片描述
⑤ 题号1035.不相交的线
我们在两条独立的水平线上按给定的顺序写下 A 和 B 中的整数。
现在,我们可以绘制一些连接两个数字 A[i] 和 B[j] 的直线,只要 A[i] == B[j],且我们绘制的直线不与任何其他连线(非水平线)相交。
以这种方法绘制线条,并返回我们可以绘制的最大连线数。
在这里插入图片描述
解析:
绘制一些连接两个数字 A[i] 和 B[j] 的直线,只要 A[i] == B[j],且直线不能相交!

直线不能相交,这就是说明在字符串A中 找到一个与字符串B相同的子序列,且这个子序列不能改变相对顺序,只要相对顺序不改变,链接相同数字的直线就不会相交。

拿示例一A = [1,4,2], B = [1,2,4]为例,相交情况如图:
在这里插入图片描述
其实也就是说A和B的最长公共子序列是[1,4],长度为2。 这个公共子序列指的是相对顺序不变(即数字4在字符串A中数字1的后面,那么数字4也应该在字符串B数字1的后面)

这么分析完之后,大家可以发现:本题说是求绘制的最大连线数,其实就是求两个字符串的最长公共子序列的长度!

那么本题就和我们刚刚讲过的这道题目动态规划:1143.最长公共子序列就是一样一样的了。

一样到什么程度呢? 把字符串名字改一下,其他代码都不用改,直接copy过来就行了。

其实本题就是求最长公共子序列的长度,介于我们刚刚讲过动态规划:1143.最长公共子序列,所以本题我就不再做动规五部曲分析了。

如果大家有点遗忘了最长公共子序列,就再看一下这篇:动态规划:1143.最长公共子序列

答:
在这里插入图片描述
在这里插入图片描述
⑥ 题号53. 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例: 输入: [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

解析:
动规五部曲如下:
1.确定dp数组(dp table)以及下标的含义
dp[i]:包括下标i之前的最大连续子序列和为dp[i]。
2.确定递推公式
dp[i]只有两个方向可以推出来:
dp[i - 1] + nums[i],即:nums[i]加入当前连续子序列和
nums[i],即:从头开始计算当前连续子序列和
一定是取最大的,所以dp[i] = max(dp[i - 1] + nums[i], nums[i]);
3.dp数组如何初始化
从递推公式可以看出来dp[i]是依赖于dp[i - 1]的状态,dp[0]就是递推公式的基础。
dp[0]应该是多少呢?
更具dp[i]的定义,很明显dp[0]因为为nums[0]即dp[0] = nums[0]。
4.确定遍历顺序
递推公式中dp[i]依赖于dp[i - 1]的状态,需要从前向后遍历。
5.举例推导dp数组
以示例一为例,输入:nums = [-2,1,-3,4,-1,2,1,-5,4],对应的dp状态如下:
在这里插入图片描述

答:
在这里插入图片描述
在这里插入图片描述
⑦ 题号392.判断子序列
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
示例 1: 输入:s = “abc”, t = “ahbgdc” 输出:true
示例 2: 输入:s = “axc”, t = “ahbgdc” 输出:false

提示:
0 <= s.length <= 100
0 <= t.length <= 10^4
两个字符串都只由小写字符组成。

答:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
⑧ 题号115.不同的子序列
给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。
字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,“ACE” 是 “ABCDE” 的一个子序列,而 “AEC” 不是)
题目数据保证答案符合 32 位带符号整数范围。

解析:
在这里插入图片描述
在这里插入图片描述
答:
在这里插入图片描述
在这里插入图片描述
⑨ 题号583. 两个字符串的删除操作
给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。

示例:
输入: “sea”, “eat”
输出: 2 解释: 第一步将"sea"变为"ea",第二步将"eat"变为"ea"

解析:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
⑩ 题号72. 编辑距离
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。

你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符
示例 1: 输入:word1 = “horse”, word2 = “ros” 输出:3 解释: horse -> rorse (将 ‘h’ 替换为 ‘r’) rorse -> rose (删除 ‘r’) rose -> ros (删除 ‘e’)

示例 2: 输入:word1 = “intention”, word2 = “execution” 输出:5 解释: intention -> inention (删除 ‘t’) inention -> enention (将 ‘i’ 替换为 ‘e’) enention -> exention (将 ‘n’ 替换为 ‘x’) exention -> exection (将 ‘n’ 替换为 ‘c’) exection -> execution (插入 ‘u’)

提示:
0 <= word1.length, word2.length <= 500
word1 和 word2 由小写英文字母组成

解析:
编辑距离终于来了,这道题目如果大家没有了解动态规划的话,会感觉超级复杂。
编辑距离是用动规来解决的经典题目,这道题目看上去好像很复杂,但用动规可以很巧妙的算出最少编辑距离。
接下来我依然使用动规五部曲,对本题做一个详细的分析:
1.确定dp数组(dp table)以及下标的含义
dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]。

这里在强调一下:为啥要表示下标i-1为结尾的字符串呢,为啥不表示下标i为结尾的字符串呢?

用i来表示也可以! 但我统一以下标i-1为结尾的字符串,在下面的递归公式中会容易理解一点。

2.确定递推公式
在确定递推公式的时候,首先要考虑清楚编辑的几种操作,整理如下:
在这里插入图片描述
在这里插入图片描述
3. dp数组如何初始化
再回顾一下dp[i][j]的定义:

dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]。

那么dp[i][0] 和 dp[0][j] 表示什么呢?

dp[i][0] :以下标i-1为结尾的字符串word1,和空字符串word2,最近编辑距离为dp[i][0]。

那么dp[i][0]就应该是i,对word1里的元素全部做删除操作,即:dp[i][0] = i;

同理dp[0][j] = j;

所以C++代码如下:
在这里插入图片描述
4.确定遍历顺序
从如下四个递推公式:
在这里插入图片描述
可以看出dp[i][j]是依赖左方,上方和左上方元素的,如图:
在这里插入图片描述
所以在dp矩阵中一定是从左到右从上到下去遍历。
在这里插入图片描述
5.举例推导dp数组
以示例1为例,输入:word1 = “horse”, word2 = "ros"为例,dp矩阵状态图如下:
在这里插入图片描述

答:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

① 题号647. 回文子串
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:
输入:“abc” 输出:3 解释:三个回文子串: “a”, “b”, “c”

示例 2:
输入:“aaa” 输出:6 解释:6个回文子串: “a”, “a”, “a”, “aa”, “aa”, “aaa”

提示:
输入的字符串长度不会超过 1000 。

解析:
动规五部曲
1.确定dp数组(dp table)以及下标的含义
布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false。
2.确定递推公式
在确定递推公式时,就要分析如下几种情况。
整体上是两种,就是s[i]与s[j]相等,s[i]与s[j]不相等这两种。

当s[i]与s[j]不相等,那没啥好说的了,dp[i][j]一定是false。
当s[i]与s[j]相等时,这就复杂一些了,有如下三种情况

情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串
情况二:下标i 与 j相差为1,例如aa,也是文子串
情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。
以上三种情况分析完了,那么递归公式如下:
在这里插入图片描述
result就是统计回文子串的数量。
注意这里我没有列出当s[i]与s[j]不相等的时候,因为在下面dp[i][j]初始化的时候,就初始为false。

3.dp数组如何初始化
dp[i][j]可以初始化为true么? 当然不行,怎能刚开始就全都匹配上了。
所以dp[i][j]初始化为false。

4.确定遍历顺序
遍历顺序可有有点讲究了。

首先从递推公式中可以看出,情况三是根据dp[i + 1][j - 1]是否为true,在对dp[i][j]进行赋值true的。

dp[i + 1][j - 1] 在 dp[i][j]的左下角,如图:
在这里插入图片描述
在这里插入图片描述
5.举例推导dp数组
举例,输入:“aaa”,dp[i][j]状态如下:
在这里插入图片描述
图中有6个true,所以就是有6个回文子串。
注意因为dp[i][j]的定义,所以j一定是大于等于i的,那么在填充dp[i][j]的时候一定是只填充右上半部分。

答:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
② 题号516.最长回文子序列
给定一个字符串 s ,找到其中最长的回文子序列,并返回该序列的长度。可以假设 s 的最大长度为 1000 。

示例 1: 输入: “bbbab” 输出: 4 一个可能的最长回文子序列为 “bbbb”。

示例 2: 输入:“cbbd” 输出: 2 一个可能的最长回文子序列为 “bb”。

提示:

1 <= s.length <= 1000
s 只包含小写英文字母

解析:
我们刚刚做过了 动态规划:回文子串,求的是回文子串,而本题要求的是回文子序列, 要搞清楚这两者之间的区别。

回文子串是要连续的,回文子序列可不是连续的! 回文子串,回文子序列都是动态规划经典题目。

答:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

力扣刷题记录 (七)动态规划(五)子序列系列 的相关文章

随机推荐

  • [Android常见问题] 自定义授权界面

    自定义授权界面 http bbs mob com thread 278 1 1 html 出处 http bbs mob com 本帖最后由 wolf 于 2016 5 6 10 30 编辑 自定义授权界面 1 准备工作 参考文档 在你的项
  • Couldn‘t find meta-data for provider with authority com.wust.camerademo

    报错信息 Couldn t find meta data for provider with authority com wust camerademo 报错原因 AndroidManifest xml 清单文件中未注册 provider
  • ae渲染出现错误是什么问题_After Effects错误:写入文件.....时发生渲染错误.输出模块失败.文件可能已损坏。(-1610153464)...

    我来回答一下 你在电脑里安装了其他下载的aex文件格式的插件 你只要把你这些插件删除掉 问题就可以解决 安装插件不正确 或者有相同的插件也出现提示框 其实 这个提示不重要 你正常开启AE以后 正常使用软件 只是 安装错误的插件 使用起来没有
  • 正负样本不平衡处理方法总结

    1 Bootstrapping hard negative mining 最原始的一种方法 主要使用在传统的机器学习方法中 比如 训练随机森林 对于每一个树就是采样booststraping方法采样 也算是随机森林的其中一个随机性表现 再比
  • java 获取当前时间所在月份的每周日期区间

    获取当前时间所在月份的每周日期区间 每周的起始日是周一 结束日期是周日 例子 假设当前时间是2020 03 04 那么这个月跨度有6周 第一周 2020 03 01 2020 03 01 第二周 2020 03 02 2020 03 08
  • 个人用户如何搭建一个全面的WEB服务器(中)

    第四 建立Win Media在线影视 按照第一步中图三 图四和图五的走法 只不过在图五中选择 流式媒体服务器 点击确定 这样系统将会自动在你的WEB服务器下创建一个Win Media流式媒体服务器站点 接下来就是如何管理这个服务器以及制作流
  • Pytorch+LSTM 的 英译中

    usr bin env Python3 coding utf 8 version v1 0 Author Meng Li contact 925762221 qq com FILE torch seq2seq py Time 2022 6
  • 【记录】看门狗定时器基础

    原文 概要 我们平时使用的电脑 由于某种原因导致动作异常 反复执行指定外的操作 或者没有任何反应 这种情况被认定为程序失控 out of control 或者程序中止了 对于用户而言 可以知道程序出现了异常 需要采取一定的措施 对于嵌入式系
  • 华为OD机试真题-任务调度【2023.Q1】

    题目内容 现有一个CPU和一些任务需要处理 已提前获知每个任务的任务ID 优先级 所需执行时间和到达时间 CPU同时只能运行一个任务 请编写一个任务调度程序 采用 可抢占优先权调度 调度算法进行任务调度 规则如下 1 如果一个任务到来时 C
  • Spring源码剖析之IOC容器创建流程

    ApplicationContextConfiguration为核心配置类 ApplicationContext applicationContext new AnnotationConfigApplicationContext Appli
  • Android手机RTMP播放工具(APK,支持秒开)

    Android手机RTMP播放工具是一款可以在安卓手机播放rtmp流的工具 基于FFmpeg openCV开发 下载地址 Android手机RTMP播放工具 APK 支持秒开 C 文档类资源 CSDN下载
  • 【后端】SSM框架体系(一)

    SSM框架 Spring 一 Spring相关概念 1 初识Spring 1 1 Spring家族 官网 https spring io 从官网我们可以大概了解到 Spring能做什么 用以开发web 微服务以及分布式系统等 光这三块就已经
  • gpexpand分析

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 本文由maxluo发表于云 社区专栏 一 gp扩容步骤 1 1 初始化机器 目标 新增加的机器需要初始化和已有机器环境一样 具体包括不限于以下内容 创建用户名 设置环境变量 创建数据
  • 一维数组寻找两个数字之和为N的组合

    问题是这样的 一维数组 包含不重复的数字 求两个数相加之和为N的所有组合 笛卡尔乘积方式 public static void Addition2WithCartesian HashSet
  • odoo中详情页字段可编辑状态与只读状态的设置

    odoo中遇到这样的情景 form详情页 比如有三个字段 name age sex 要求当name为空是age和sex可编辑 当name有值时age和sex只读 可使用attrs进行限制如下
  • 欧拉计划问题五matlab实现

    Problem 5 Smallest multiple 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without
  • HDLBits练习(五)锁存器和DFF

    1 创建具有高电平有效同步复位的8 D触发器 触发器必须重置为0x34而不是零 所有DFF应由clk的负边缘触发 module top module input clk input reset input 7 0 d output 7 0
  • nvprof 使用笔记

    1 nvprof metrics gld efficiency gst efficiency myproc 检测内存加载存储效率 2 nvprof query metrics 查看所有能用的参数命令 3 nvprof metrics sta
  • java mail 报错550 Mailbox not found or access denied

    运行了几年的发邮件程序 最近集体发邮件报错 org springframework mail MailSendException Failed messages javax mail SendFailedException Invalid
  • 力扣刷题记录 (七)动态规划(五)子序列系列

    题号300 最长递增子序列 给你一个整数数组 nums 找到其中最长严格递增子序列的长度 子序列是由数组派生而来的序列 删除 或不删除 数组中的元素而不改变其余元素的顺序 例如 3 6 2 7 是数组 0 3 1 6 2 2 7 的子序列