当前位置: 首页 > news >正文

算法训练营DAY51|300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

本期是求子序列的新的一期,题目前两道有一些相似之处,思路差不多,第三道有一点难度,但并不意味着第一道没有难度,没有做过该类型题的选手,并不容易解出题解。

300. 最长递增子序列 - 力扣(LeetCode)https://leetcode.cn/problems/longest-increasing-subsequence/

题目大意是给一个数组,要求返回最长的递增的序列,题目要求是删除中间一些元素,或者不删除也可以,返回最长的递增的数组长度,又是一道这种题目,如果你是之前做过类似题目大意的朋友应该知道,通常来说要求可以删除中间元素的,通常我们都不是真的删除数据,而是通过遍历来间接的实现删除中间的数据的过程,换句话来说,不是真正删除数据,而是要删除的数据我们不处理它。 

dp数组的含义:dp【i】代表到该位置为止,i之前包括i的最长的递增子序列是多大。但是需要注意的是,整体的最长的递增子序列,可不一定是dp数组的最后一个数据,因为很可能,我们要找的最长递增序列结尾在前面就已经出现了,而遍历到数组最后一个位置,可能只是不同的递增子序列路线,不一定是长的。

递推公式:由于递增子序列,很有可能不是连续的,需要删除部分数据,那么我们如何实现这一部分的代码呢?答案是用两个循环,一个是外层循环控制遍历到数组中的哪一个位置了,另一个内层循环是重复遍历从起始位置到i这个位置,如果出现前面的0-i的数据比当前遍历到的数小,那么递增子序列长度+1,这也就是相当于不符合条件的数据我们直接略过去,符合条件的再使长度+1,间接的删除了多余数据

也就是if(nums【j】< nums【i】)dp【i】=max(dp【i】,dp【j】+1)

取最大值,看看它原本的大还是遍历完的最长递增子序列长度大。每次j都会从头开始遍历一次,看看这回多出来的那个数据是否能使子序列长度增加。

dp数组初始化:dp数组的初始化都是初始化为1,这是因为如果只有一个数据的话,那么最长递增子序列肯定是1,不可能返回0,而其他的为什么也初始化为1呢?因为如果出现大于1的递增子序列长度那么就一定会被递推公式所覆盖,所以我们都初始化为1。

遍历顺序:都是从前向后遍历,不用多说。

class Solution {
public:int lengthOfLIS(vector<int>& nums) {vector<int>dp(nums.size(),1);int result=1;for(int i=1;i<nums.size();i++){for(int j=0;j<i;j++){if(nums[i]>nums[j])dp[i]=max(dp[i],dp[j]+1);}if(result<dp[i])result=dp[i];}return result;}
};

 代码中的result的用处就是,记录最长的递增子序列有多长,然后最后返回它。


674. 最长连续递增序列 - 力扣(LeetCode)https://leetcode.cn/problems/longest-continuous-increasing-subsequence/这道题和上一道题很像,只不过这道题我们要求的是连续的递增子序列了,连续的递增子序列,我个人认为要比非连续的要好写,或者说好想一点。

dp数组含义:dp数组的含义和上一道题一样,也是到该位置为止,i之前包括i的最长的连续递增子序列是多长,但是我觉得这种含义太抽象了,不利于初学者理解,我认为可以将这句话翻译为以i结尾的这条递增序列有多长,这其实也就间接的证明了我们之前所说的含义,即最后一个下标的dp数组所代表的数据,并不一定是最大的。因为它代表的应该是以i为结尾的这条递增序列最长有多长。

递推公式:由于是连续的最长递增序列,所以我们只看是否是连续递增就可以了,那么连续就体现在上一个数字和这一个数字的比较

if(nums【i】==nums【i-1】)dp【i】=dp【i-1】+1;

dp数组初始化和遍历顺序都和上一道题一样,不做赘述。

class Solution {
public:int findLengthOfLCIS(vector<int>& nums) {vector<int>dp(nums.size(),1);int result=1;for(int i=1;i<nums.size();i++){if(nums[i]>nums[i-1])dp[i]=dp[i-1]+1;result=max(result,dp[i]);}return result;}
};

718. 最长重复子数组 - 力扣(LeetCode)https://leetcode.cn/problems/maximum-length-of-repeated-subarray/这道题是略有难度的一道题,为什么说它略有难度呢?并不是递推公式有多难理解,而是dp数组的的表示,要清楚的想到有一些难度。

dp数组的含义:这是给我们两个数组,然后让我们求重复的连续部分最长有多长,这是我们就需要使用二维数组来表示了,其中一维表示一个数组,另一维表示另一数组,而dp【i】【j】表示的是第一个数组的i-1位置,下标对应的第二个数组的j-1下标位置,最长的重复子数组有多长,那么为什么我们要表示i-1和j-1呢?直接表示i和j不好吗?这样定义是为了方便dp数组的初始化,在下面还有对此处的详解。

递推公式:从哪个方向上能够推出dp【i】【j】呢?当数组1的i-1下标位置的数字和数组2下标为j-1的位置数字相等的时候,不就是说明两数组有一数字重复吗,此时就是长度+1,那么递推公式就理所当然的是if(nums1【i-1】==nums2【j-1】)dp【i】【j】=dp【i-1】【j-1】+1;

就是上一个长度再加上这回匹配成功的长度1。

dp数组的初始化:看到这里相信大家可能已经带有一些疑问了,这样定义dp数组那么当遍历到i和j等于0的时候,不就出问题了吗?这也正是初始化所要解决的问题,正是因为我们这样定义dp数组导致了当i和j其中一个为0时候,是非法的,所以我们初始化第一行和第一列时候全部初始化为0,其余部分因为有递推公式的存在,每个位置是依靠前一个位置的值,所以i和j非0部分初始化为什么都可以。那么为什么我们要这样定义数组呢?因为如果dp【i】【j】就是表示它处在i和j的位置上时候有多长,这会导致初始化i和j其一等于0时,也就是二维数组的第一行和第一列可能不全为0,这会增大初始化的代码强度,可能第一个数组i==0的时候第二个数组的j对应某位置两数组有数据相等,也就是第一行某处有位置应该初始化为1,讲到这里大家反复揣摩一下,用笔画一下,可能就明白了。

遍历顺序:遍历顺序还是从前向后,两个for循环,分别遍历第一个数组和第二个数组,从前向后查看是否有相等的元素出现。

class Solution {
public:int findLength(vector<int>& nums1, vector<int>& nums2) {vector<vector<int>>dp(nums1.size()+1,vector<int>(nums2.size()+1,0));int result=0;for(int i=1;i<=nums1.size();i++){for(int j=1;j<=nums2.size();j++){if(nums1[i-1]==nums2[j-1])dp[i][j]=dp[i-1][j-1]+1;result=max(result,dp[i][j]);}}return result;}
};

以上就是本章的全部内容,子序列问题起初做都没有什么思路,要勤加练习思维,才能够想出用动态规划解决问题的思路。

http://www.lryc.cn/news/791.html

相关文章:

  • mac:彻底解决-安装应用后提示:无法打开“XXX”,因为无法验证开发者的问题;无法验证此App不包含恶意软件
  • CPU 指标 user/idle/system 说明
  • Thinkphp大型进销存ERP源码/ 进销存APP源码/小程序ERP系统/含VUE源码支持二次开发
  • hgame2023 WebMisc
  • 67. Python的绝对路径
  • VHDL语言基础-组合逻辑电路-加法器
  • 内存检测工具Dr.Memory在Windows上的使用
  • J6412四网口迷你主机折腾虚拟机教程
  • 电子招标采购系统—企业战略布局下的采购寻源
  • elasticsearch 之 mapping 映射
  • 2023年rabbitMq面试题汇总2(5道)
  • 电视剧《狂飙》数据分析,正片有效播放市场占有率达65.7%
  • cas单点登录后重定向次数过多问题以及调试cas-dot-net-client
  • 【监控】Prometheus(普罗米修斯)监控概述
  • opencv+python物体检测【03-模仿学习】
  • 计算机科学基础知识第二节讲义
  • openssl genrsa 命令详解
  • C语言标准 —— C89(C90)、C99、C11、C17、C2X
  • 基于Java+Dubbo设计的智能公交查询系统
  • go语言的并发编程
  • 亚马逊要求UL94防火测试阻燃测试标准及项目
  • ClickHouse 合并树表引擎 MergeTree 原理分析
  • 用YOLOv8推荐的Roboflow工具来训练自己的数据集
  • 三层交换机【实验】
  • Anolis 8.6 部署 Kafka 3.3.1 安装和测试(二)
  • sed和awk
  • 使用STM32 CUBE IDE配置STM32F7 用DMA传输多通道ADC数据
  • linux 学习(持续更新)
  • Nacos【一】Nacos集群部署配置
  • “亚洲一号”也能上市?REITs背后的物流设施风起云涌