【LeetCode】300.最长递增子序列

首先分析这个问题,以示例1为例。

已经求得最大递增子序列长度为4,而且该子序列中最后一个数为101,

那么一定存在一个数ai,使得ai以及ai之前的所有数组成的序列中,

最大递增子序列长度为3,而且该子序列中最后一个数为ai。

我们记dp[ i ]为,从第0个数到第 i-1 个数所组成的序列中,最大递增子序列的长度。那么在示例1中,dp[ 0 ]=1;dp[ 1 ]=1;dp[ 2 ]=1;dp[ 3 ]=2;dp[ 4 ]=2;dp[ 5 ]=3;dp[ 6 ]=4;dp[ 7 ]=4.

示例2中,dp[ 0 ]=1;dp[ 1 ]=2;dp[ 2 ]=2;dp[ 3 ]=3;dp[ 4 ]=3;dp[ 5 ]=4.

可以看出dp[ i ]的值是依次以某种规律递增的。

但由于要求是严格递增的子序列,因此ai之前比ai大的数就不再纳入考虑。

综上所述,dp[ i ]的值可以这么确定:找到ai之前比它小的数ak,dp[ i ]=dp[ k ]+1,最后为了使dp[i]最大,就必须使dp[ k ]最大,因此要在ai之前的数里找到最大的dp[ k ],由此就得到了dp[ i ]。

cpp 复制代码
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int dp[2510]={0};
        int len=nums.size();
        for(int i=0;i<len;++i)
        {
            dp[i]=1;
//子序列长度最小值是 1
            for(int j=0;j<i;++j)
//第二层循环的目的是找到nums[i]之前比它小的数nums[j],
//找到最大值dp[j]之后,dp[i]=dp[j]+1
//下面这种写法等效于上面的分析,不过省了一点代码
            {
                if(nums[j]<nums[i])
                dp[i]=max(dp[i],dp[j]+1);
            }
        }
        int MAX=0;
        for(int i=0;i<len;++i) MAX=max(MAX,dp[i]);
//这里需要遍历整个dp数组找出最大值,原因在下面
        return MAX;
    }
};

需要注意的是:这种方法最后需要遍历一遍dp数组来找出最大值,因为如果给出的序列如下:

元素:1,3,6,7,9,4,10,5,6

编号:0 1 2 3 4 5 6 7 8

那么dp[ 6 ]=6,但是计算dp[ 5 ]时,由于6、7、9都比4大,因此只考虑了dp[ 5 ]=max(dp[ 5 ],dp[ 1 ]+1),而dp[ 1 ]=2,故dp[ 5 ]=3;这就导致计算dp[ 7 ]=max(dp[ 7 ],dp[ 5 ]+1)=4,同理dp[8]=5,如果直接输出dp[ len ],就错了。

相关推荐
玄同7653 分钟前
Python Random 模块深度解析:从基础 API 到 AI / 大模型工程化实践
人工智能·笔记·python·学习·算法·语言模型·llm
Pluchon6 分钟前
硅基计划4.0 算法 简单模拟实现位图&布隆过滤器
java·大数据·开发语言·数据结构·算法·哈希算法
独断万古他化12 分钟前
【算法通关】前缀和:和为 K、和被 K整除、连续数组、矩阵区域和全解
算法·前缀和·矩阵·哈希表
历程里程碑14 分钟前
普通数组-----除了自身以外数组的乘积
大数据·javascript·python·算法·elasticsearch·搜索引擎·flask
AI视觉网奇16 分钟前
blender 导入fbx 黑色骨骼
学习·算法·ue5·blender
weixin_4684668521 分钟前
目标识别精度指标与IoU及置信度关系辨析
人工智能·深度学习·算法·yolo·图像识别·目标识别·调参
多恩Stone25 分钟前
【3D AICG 系列-8】PartUV 流程图详解
人工智能·算法·3d·aigc·流程图
铸人29 分钟前
再论自然数全加和-质数的规律
数学·算法·数论·复数
历程里程碑2 小时前
Linux22 文件系统
linux·运维·c语言·开发语言·数据结构·c++·算法
YGGP3 小时前
【Golang】LeetCode 128. 最长连续序列
leetcode