300.最长递增子序列
😄300.最长递增子序列
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
思路
基本思想
当前位置的最长递增子序列的长度肯定和之前的元素有关,所以考虑动态规划,主要是递推方程的确定,本题中dp[j]
代表第j个元素之前有多少个元素比当前元素大,包括本身,因为单独一个元素,递增子序列长度为1,换句话说就是以nums[i]
结尾的最长递增子序列长度
对当前元素来说,前面有很多元素,只要比其中的某一个元素大,都算是递增,此时递增子序列的长度就有可能增加,但是也不是肯定增加,举例来说,[4,3,5,6,2,8]中dp[8]=4而不是2,因为dp[8]取的是前面的元素中最长的递增子序列长度,而不是遇到一个比他小的就更新
最终的递推方程为: $$ dp[i]=max(dp[i],dp[j]+1) $$ 要看当前更新是不是能变大
不能直接使用一下判断语句更新dp,这个判断语句是连续递增时可以使用:
|
|
这样在例子[4,10,4,3,8,9]中会出错,元素9比元素8大,但是他们两个的dp是一样的,因为前面有一个元素10,导致他们不能随意的增加
在之前的元素中找出最长的递增子序列,当前元素之前的所有比当前元素小的元素组成了最长的递增子序列
执行流程
初始化dp数组,初始值为1,因为[7,7,7,7]的最终结果为1
按照递推方程进行更新
对于每一个元素,找出以它结尾的最长递增子序列
返回最终结果
由于最后一个元素不一定是全局最大的元素,所以dp数组的最后一个元素保存的不是最终的结果,需要找出dp数组中最大的值作为最终的结果
代码
根据以上分析,得出以下代码:
|
|
总结
确定好递推方程,判断当前元素之前有几个比他小的,更新当前元素结尾的最长递增子序列,最终返回最大的序列长度作为最终的结果
对于每个元素都判断之前有几个元素比他小,从而更新自己的最长递增子序列