力扣● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组

news2024/9/27 18:41:55

● 300.最长递增子序列

1.dp数组含义。dp[i]:以nums[i]为结尾的递增子序列的最大长度。

注意一定是以nums[i]结尾,如果dp[i]定义错误的话,暴力也不知道咋整。

2.递推公式。这道题与背包的单词划分比较像,一个单层循环是弄不出来的,外层循环i,内层循环j。即当前下标i的递增子序列长度,其实和i之前的下表j的子序列长度有关系。准确的说,i的递增子序列长度就是由[0,i-1]范围内的子序列长度得到的,要取他们中的一个最大值。分析如下:

如果nums[i]比nums[j]小或者相等,那么就不能把nums[i]拼到nums[j]结尾的序列上,即不能根据dp[j]得到dp[i],因为dp[i]一定是nums[i]为结尾的递增子序列的最大长度,nums[i]要比这个序列中的其他元素都大。

所以递推公式只考虑nums[i]比nums[j]大的情况,一开始,j=i-1,这个序列里面只有i自己,所以dp[i]=1,然后从后往前依次比较要不要加入j的子序列,有可能i加入j的这个子序列后长度更大,长度是dp[j]+1;也有可能加入后长度没变大,所以保持原样。

所以dp[i]应该取这两个的较大值:dp[i]=max(dp[j]+1,dp[i]);

代码随想录:注意这里不是要dp[i] 与 dp[j] + 1进行比较,而是我们要取dp[j] + 1的最大值(从后往前依次比较取得的)。

公式结合例子更好理解,举例:

nums = [10,9,2,5,3,7,101,18]

到元素3的时候,dp[4]一开始是1,意味着这个子序列只有自己;与5比较比5小,不能把自己拼到5的子序列后面,即不能由dp[3]得到,跳过;与2比较,可以拼到2后面,取max为2;比9大;比10大。所以dp[4]=2。

3.初始化。dp[i]的最大长度,一开始只有它自己一个元素组成一个序列,所以均初始化为1。

4.遍历顺序。根据递推公式过程,i从左到右,j从右到左。

5.打印。

代码如下。仍然注意dp数组的含义,最后不是返回dp[nums.size()-1],而是返回dp中的最大值。

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


● 674. 最长连续递增序列

这道题和上一道题的区别是:递增序列是连续的,那么不需要内层循环遍历[i-1,0],因为nums[i]只能拼接到nums[i-1]上面,即根据dp[i-1]得到dp[i],再前面的dp元素跟i扯不上关系。

所以一层循环就能实现,也不用比较max值。

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


● 718. 最长重复子数组

1.dp数组含义。

根据上面两道题,dp[i]数组含义也是以下标i元素为结尾的所要求的特定序列的长度,根据i前面的dp得到i的dp。

因为两个数字,所以dp数组得变成二维:dp[i][j]:以nums1[i-1]或者说以nums2[j-1]元素结束的公共子序列的最大长度,其实就是两个子数组(2个子数组分别是:nums1前i个;nums2前j个)的公共后缀的最长长度。所以是两层循环,遍历nums1的前1个到前n1个,其中又遍历nums2的前1个到前n2个,最后返回过程中的比较得出的最大长度maxlen。

所以这个结论一定要贯穿过程中:从数组1  i-1下标、数组2  j-1下标开始,挨个从右往左倒着比较,有dp[i][j]个元素是相同的。如123,103:dp[3][3]=1。

2.递推公式。

根据上面的那个结论,dp[i][j]说明nums1[i-1]==nums2[j-1],而且nums1的i-2前面和nums2的j-2前面还有dp[i][j]-1长度的元素是相同的。根据定义:nums1的i-2前面和nums2的j-2前面的公共后缀最长长度是dp[i-1][j-1]

所以if(nums1[i-1]==nums2[j-1]) dp[i][j]-1=dp[i-1][j-1]。即dp[i][j] = dp[i - 1][j - 1] + 1;

3.初始化。

dp[i][j]中i、j有一个0都是无意义的,所以直接初始化为0。

这就是为什么dp数组下标相对于nums下标+1的原因,偏移1个可以直接初始化为0,如果不偏移,dp[i][j]是nums1前i+1个和nusm2前j+1个子数组的公共后缀最长长度,那么第1行和第1列需要挨个判断,相等的话为1,不相等为0。而且偏移一个也是好理解的:nums1前i个;nums2前j个的2个子数组。

4.遍历顺序。两层循环要统计出所有子数组的情况,所以两个数组 要从0到size()-1,又dp数组下标相对于nums下标+1,所以i从1到nums1.size(),j从1到nums2.size()。

5.打印。

代码:

class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        int n1=nums1.size();
        int n2=nums2.size();
        int maxlen=0;
        vector<vector<int>> dp(n1+1,vector<int>(n2+1,0));
        for(int i=1;i<=n1;++i){
            for(int j=1;j<=n2;++j){
                if(nums1[i-1]==nums2[j-1])//可以 以nums1[i-1]/nums2[j-1]作为结尾,递推
                {
                    dp[i][j]=dp[i-1][j-1]+1;
                    maxlen=max(maxlen,dp[i][j]);
                }
            }
        }
        return maxlen;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1517127.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AJAX 02 案例、Bootstrap框架

AJAX 学习 AJAX 2 综合案例黑马 API01 图书管理Bootstrap 官网Bootstrap 弹框图书管理-渲染列表图书管理-添加图书图书管理-删除图书图书管理 - 编辑图书 02 图片上传03 更换图片04 个人信息设置信息渲染头像修改补充知识点&#xff1a;label扩大表单的范围 AJAX 2 综合案例 黑…

深入剖析Mysql事务和Spring事务,mongodb面试题2024

注意max_trx_id并不是m_ids中的最大值&#xff0c;事务id是递增分配的。比方说现在有id为1&#xff0c;2&#xff0c;3这三个事务&#xff0c;之后id为3的事务提交了。那么一个新的读事务在生成ReadView时&#xff0c;m_ids就包括1和2&#xff0c;min_trx_id的值就是1&#xff…

OSG编程指南<二十>:OSG路径动画

1、路径动画 如果读者耐心地读到这里,已经对路径动画不陌生了。因为前面很多处已经涉及路径动画,在很多示例中也用到了路径动画。路径动画就是按一定的插值方式生成路径,物体对象按照生成的路径或预先指定的路径来完成相应的动作的动画。 在 OSG 中,管理路径动画的核心类主…

数据结构——循环链表,双向链表,线性表和有序表的合并详解

目录 1.循环链表 1.带尾指针循环链表的合并 代码示例&#xff1a; 2.双向链表 代码示例&#xff1a; 1.双向链表的插入 ​代码示例&#xff1a; 2.双向链表的删除 代码示例&#xff1a; 3.单链表&#xff0c;循环链表&#xff0c;双向链表时间效率的比较 4.顺序表和链…

LSM树(Log-Structured-Merge-Tree)

学习笔记&#xff1a;参考LSM树详解 - 知乎 (zhihu.com) NoSQL&#xff08;HBase,LevelDB,RocksDB&#xff09;采用LSM树 核心&#xff1a;利用顺序写来提高性能&#xff0c;但因为分层&#xff08;内存和文件两部分&#xff09;的设计会降低读性能。//牺牲小部分读性能来换高…

Hack The Box-Codify

目录 信息收集 rustscan nmap dirsearch WEB 提权 get user get root 信息收集 rustscan ┌──(root㉿ru)-[~/kali/hackthebox] └─# rustscan -b 2250 10.10.11.239 --range0-65535 --ulimit4500 -- -A -sC .----. .-. .-. .----..---. .----. .---. .--. .-. …

漏洞复现-金蝶系列

漏洞复现-金蝶系列 Apusic 金蝶天燕Apusic 应⽤中间件代码命令执⾏金蝶云星空RCE金蝶云OA星空 CommonFileserver 任意文件读取金蝶云星空 管理中心介绍⾦蝶 EAS 系统存在⽬录遍历金蝶EAS myUploadFile任意文件上传实战之金蝶RCE上传绕过金蝶云金蝶云SaveUserPassport存在反序列…

音视频实战---读取音视频文件的AAC音频保存成aac文件

1、使用avformat_open_input函数打开音视频文件 2、使用avformat_find_stream_info函数获取解码器信息。 3、使用av_dump_format设置打印信息 4、使用av_init_packet初始化AVPacket。 5、使用av_find_best_stream查找对应音视频流的流下标。 6、使用av_read_frame读取音视…

移动硬盘分区误删?别担心,数据恢复来帮忙!

在日常使用移动硬盘的过程中&#xff0c;有时会因为各种原因导致分区被误删。这种情况一旦发生&#xff0c;很多人会感到惊慌失措&#xff0c;担心数据丢失无法找回。然而&#xff0c;只要及时采取正确的数据恢复措施&#xff0c;大多数情况下都能够成功恢复误删的分区和数据。…

变量直接赋值、浅拷贝、深拷贝、递归、异常

对象拷贝(对象存在堆中) 变量直接赋值 赋值 就是一个&#xff0c;比如let obj2obj1 这就是赋值&#xff0c;只是把栈中存储的值&#xff0c;赋值给另一个变量 把obj1在栈中的地址&#xff0c;赋值给obj2 <script>let str hellolet str2 str //把str的值,赋值给str2.也…

公派访问学者申请被拒签的原因有哪些?

在申请公派访问学者时&#xff0c;拒签是一种常见的结果&#xff0c;其原因多种多样。首先&#xff0c;申请材料不完整或者不符合要求可能是导致拒签的主要原因之一。例如&#xff0c;个人简历、研究计划书、推荐信等材料未能清晰地展示申请人的学术背景和研究意图&#xff0c;…

想零基础转行Python开发,怎么学习呢?

转行零基础学Python编程开发难度大吗&#xff1f;从哪学起&#xff1f;近期很多小伙伴问我&#xff0c;如果自己转行学习Python&#xff0c;完全0基础能否学会呢&#xff1f;Python的难度到底有多大&#xff1f;今天&#xff0c;小编就来为大家详细解读一下这个问题。 学习 Py…

蓝桥杯刷题|02入门真题

[蓝桥杯 2022 省 B] 刷题统计 题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a 道题目&#xff0c;周六和周日每天做 b 道题目。请你帮小明计算&#xff0c;按照计划他将在第几天实现做题数大于等于 n 题? 输入格式 输入一行包含三个整数…

用这个工具制作企业宣传册,效果也太酷了

​随着市场的竞争日益激烈&#xff0c;企业的宣传册成为了展示企业形象和实力的重要途径。而如何制作一份既美观又实用的宣传册&#xff0c;成为了许多企业家和设计师们关注的焦点。 今天&#xff0c;笔者要向大家介绍的就是这样一款工具&#xff0c;它能够让用户轻松制作出既具…

软件测试中的AI-为什么它在软件自动化测试中很重要?

通俗地说&#xff0c;人工智能&#xff08;AI&#xff09;是计算机科学的一个领域&#xff0c;它专注于使机器“智能化”。所谓智能&#xff0c;就是使系统能够像人类一样学习和做出决策。因此&#xff0c;人工智能机器将能够学习如何在特定情况下做出反应&#xff0c;然后根据…

基于springboot社团管理系统的设计与实现

互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#xff0c;劳…

使用vscode+clangd+bear+publickeyssh远程开发Linux程序

目录 配置ssh密钥远程登录登录远程Linux主机安装必要软件安装vscode插件1.安装remote-ssh插件2.通过vscode远程连接到linux机器3.在远程安装插件clangd4.关闭C/C Intellense engine 使用vscodeclangdbear1.修改Makefile2.编译内核3.结果 配置ssh密钥远程登录 一定要配置成密钥…

Nacos安装遇到的问题

Windows安装nacos双击startup.cmd执行出错 改成用cmd窗口输入命令 startup.cmd -m standalone启动之后登录的问题 权限认证失败 没有 命名空间的访问权限&#xff01; 把默认的登录url改成&#xff1a; http://127.0.0.1:8848/nacos/#/login登录之后&#xff0c;点击导入配置…

基于springboot实现驾校信息管理系统项目【项目源码+论文说明】

基于springboot实现驾校信息管理系统演示 摘要 随着人们生活水平的不断提高&#xff0c;出行方式多样化&#xff0c;也以私家车为主&#xff0c;那么既然私家车的需求不断增长&#xff0c;那么基于驾校的考核管理也就不断增强&#xff0c;那么业务系统也就慢慢的随之加大。信息…

用python证明一生一世很容易,但要爱一个人一生一世就比较难了

个人简介 &#x1f468;&#x1f3fb;‍&#x1f4bb;个人主页&#xff1a;九黎aj &#x1f3c3;&#x1f3fb;‍♂️幸福源自奋斗,平凡造就不凡 &#x1f31f;如果文章对你有用&#xff0c;麻烦关注点赞收藏走一波&#xff0c;感谢支持&#xff01; &#x1f331;欢迎订阅我的…