首页 > 其他分享 >DAY48|| 300.最长递增子序列 | 674. 最长连续递增序列 | 718. 最长重复子数组

DAY48|| 300.最长递增子序列 | 674. 最长连续递增序列 | 718. 最长重复子数组

时间:2024-10-31 16:16:57浏览次数:3  
标签:nums 递增 数组 序列 最长 dp

 300.最长递增子序列

300. 最长递增子序列 - 力扣(LeetCode)

给你一个整数数组 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

dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度

if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);

注意这里不是要dp[i] 与 dp[j] + 1进行比较,而是我们要取dp[j] + 1的最大值

初始值大小至少是1,且从前往后遍历。

 

代码 

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if(nums.size()<=1)return nums.size();
        vector<int>dp(nums.size(),1);
        int result=0;
        for(int i=1;i<nums.size();i++)//背包
        {
            for(int j=0;j<i;j++)//在 i 之前查找比 nums[i] 小的元素 nums[j]。如果 nums[i] > nums[j],说明 nums[i] 可以接在 nums[j] 后形成一个更长的递增子序列,所以更新 dp[i] 为 dp[j] + 1,并取 dp[i] 和 dp[j] + 1 的最大值,保证 dp[i] 是最大的递增子序列长度。
            {
                if(nums[i]>nums[j])dp[i]=max(dp[i],dp[j]+1);
            }
            if(dp[i]>result)result=dp[i];//更新每一段0到i的最大递增子序列
        }
        return result;
        
    }
};

674. 最长连续递增序列

674. 最长连续递增序列 - 力扣(LeetCode)

给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。

连续递增的子序列 可以由两个下标 l 和 rl < 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。

dp思路。

dp[i]:以下标i为结尾的连续递增的子序列长度为dp[i]

如果 nums[i] > nums[i - 1],那么以 i 为结尾的连续递增的子序列长度 一定等于 以i - 1为结尾的连续递增的子序列长度 + 1 。

即:dp[i] = dp[i - 1] + 1;

代码 

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

            if(dp[i]>result)result=dp[i];
        }
        return result;
    }
};

本题很简单,用贪心思路也差不多。

718.最长重复子数组

718. 最长重复子数组 - 力扣(LeetCode)

给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 

示例 1:

输入:nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7]
输出:3
解释:长度最长的公共子数组是 [3,2,1] 。

示例 2:

输入:nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0]
输出:5

 思路

难在是有两个数组,需要同时遍历取公共的最长子数组的长度。

dp[i][j] :以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j]。

即当A[i - 1] 和B[j - 1]相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1;

根据dp[i][j]的定义,dp[i][0] 和dp[0][j]其实都是没有意义的!

但dp[i][0] 和dp[0][j]要初始值,因为 为了方便递归公式dp[i][j] = dp[i - 1][j - 1] + 1;

所以dp[i][0] 和dp[0][j]初始化为0。

遍历顺序,从小到大,但两个数组谁在外面就没有讲究了。

 

代码

class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        //创建了一个二维数组 dp,用于记录相同位置的公共子数组的长度。dp[i][j] 表示 nums1 的前 i 个元素和 nums2 的前 j 个元素所能形成的最长公共子数组的长度。额外增加的 1 个行和列是为了处理边界情况,便于代码编写
        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++)
            {
                 //表明在当前位置上有一个公共元素。令 dp[i][j] = dp[i - 1][j - 1] + 1,即当前匹配的公共子数组长度等于前一位置的公共子数组长度加 1。如果不相等,dp[i][j] 保持为初始值 0。
                if(nums1[i-1]==nums2[j-1])
                dp[i][j]=dp[i-1][j-1]+1;//如果相等,则在对应的二维数组位置(也可以理解为坐标)

                if(dp[i][j]>result)result=dp[i][j];
            }
        }
        return result;
    }
};

标签:nums,递增,数组,序列,最长,dp
From: https://blog.csdn.net/2301_79865280/article/details/143356154

相关文章

  • 【时间序列分析】平稳时间序列分析——Wold分解定理和延迟算子
    Wold分解定理(这个定理是平稳时间序列分析的理论基石。)对于任意一个离散平稳时间序列,它都可以分解为两个不相关的平稳序列之和,其中一个为确定性的(deterministic),另一个为随机性的(stochastic) xₜ=Vₜ+ξₜ,{V₁}为确定性平稳序列,ξ₁为随机性平稳序列式中:确定性......
  • Leetcode刷题Python之3165.不包含相邻元素的子序列的最大和
    提示:利用线段树解决不包含相邻元素的子序列最大和问题。文章目录一、题目描述示例二、解题思路1.思路分析2.线段树的状态设计3.线段树的操作三、代码实现代码详细解释四、总结时间复杂度分析一、题目描述给定一个整数数组nums和一个二维数组queries,其中q......
  • 最长公共前缀
    最长公共前缀题目链接:牛客描述给你一个大小为n的字符串数组strs,其中包含n个字符串,编写一个函数来查找字符串数组中的最长公共前缀,返回这个公共前缀。示例输入:["abca","abc","abca","abc","abcc"]返回值:"abc"思路step1:确定第i个与第i+1个字符串子串相同的公共......
  • 计量经济学(十五)的理论基础——时间序列分解定理
    时间序列分析是数据科学中的一个重要分支,旨在探索和理解随着时间变化的数据背后的模式和结构。无论是在金融市场预测、经济政策分析、环境监测还是医学研究中,时间序列数据的广泛应用证明了其在预测未来趋势、制定决策和风险管理方面的重要性。然而,时间序列数据的复杂性和多样性使......
  • 代码随想录算法训练营day31| 56. 合并区间 738.单调递增的数字
    学习资料:https://programmercarl.com/0056.合并区间.html#算法公开课贪心PART5over学习记录:56.合并区间(也是找重叠区间,但是是跟result[-1]比,只用比右边界;更新result[-1][1]为更大值)点击查看代码classSolution(object):defmerge(self,intervals):"""......
  • BasicTS: 探索多元时间序列预测的进展: 综合基准和异质性分析(综述、长序列预测、时空
    2024年10月29日,在读一篇长序列预测&时空预测的综述的博客,记录一下自己需要的内容。原博客链接:「万字长文」长序列预测&时空预测,你是否被这些问题困扰过?一文带你探索多元时间序列预测的研究进展!论文:ExploringProgressinMultivariateTimeSeriesForecasting:Comprehensive......
  • 时间序列预测---Prophet
    更多细节可见官网地址:https://facebook.github.io/prophet/docs/quick_start.html#python-api一、模型介绍Prophet是facebook开源的的一个时间序列预测算法,特别适合于处理具有季节性和趋势的数据。主要思想是将数据分解为如下三个部分:趋势、季节性、节假日和特殊事件。y......
  • 时间序列分析:一种二次指数平滑法构建的纺织生产布料年产量线性预测模型 | 基于SQL语言
    目录0问题描述1 符号规定与基本假设 2模型的分析与建立 3模型的求解【基于SQL语言实现】3.1数据准备3.2问题分析步骤1:计算初始值。步骤2:计算一次平滑值。步骤3:计算二次平滑值 步骤4:计算直线趋势模型的系数 及步骤5:构建线性预测模型进行结果预测3.3结......
  • ISSA+CNN+BIGRU+attention时间序列预测代码
    1.ISSA(改进的麻雀优化算法)功能:ISSA用于优化模型参数(如CNN和BIGRU的超参数),帮助提高模型的性能和准确性。机制:寻食策略:模拟麻雀在觅食过程中如何探索和利用资源,通过随机游走和局部搜索,寻找最优解。自适应权重:ISSA可以根据搜索空间动态调整探索和利用的权重......
  • Fastjson枚举序列化和反序列化的推荐实现
    一、背景项目中定义了很多dto,包含枚举类型,而且这些枚举全都自定义标志码。比如7001对应某种操作。返回前台时,需要转化为对应的7001,前台传入后台时也希望7001转化为枚举。二、研究思路一开始,研究了fastjson的默认实现。发现只有不自定义类似7001这种默认值的时候,可以自动转化......