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

2024-03-11 04:44

本文主要是介绍力扣● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

● 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. 最长重复子数组

这篇关于力扣● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/796678

相关文章

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

Spring的RedisTemplate的json反序列泛型丢失问题解决

《Spring的RedisTemplate的json反序列泛型丢失问题解决》本文主要介绍了SpringRedisTemplate中使用JSON序列化时泛型信息丢失的问题及其提出三种解决方案,可以根据性... 目录背景解决方案方案一方案二方案三总结背景在使用RedisTemplate操作redis时我们针对

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方