0%

LeetCode-300-最长递增子序列

LeetCode 300 最长递增子序列

300.最长递增子序列

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

动态规划

此处子序列是不连续的。本题的重点依旧是动态规划数组的定义:也就是如何从i推导到i+1。

  1. 动态规划数组的定义:定义数组 dp[i] 表示 i 之前包括 i 的以 nums[i] 结尾的最长递增子序列的长度。本题的重点应该就是关注于递增序列的结尾元素,因此要让递增序列继续增长,那么就需要和序列末尾的元素进行比较,因此将动态规划数组做此定义。

  2. 动态规划数组的推导:那么 dp[i+1] 则表示,在 i+1 之前包括 i+1 的以 nums[i+1] 结尾的最长递增子序列的长度,那么推导为:dp[i+1]=max(dp[j])+1 其中 j=0...i 并且要求 nums[j]<nums[i+1]

  3. 动态规划数组的初始化:dp[0] 只包含一个元素,最长的递增子序列长度为1, dp[0]=1

  4. 动态规划数组的遍历顺序:从前向后遍历

  5. 举例验证:输入 nums=[10,9,2,5,3,7,101,18] 动态规划数组的变化过程为:

dp=[1,1,0,0,0,0,0,0]
dp=[1,1,1,0,0,0,0,0]
dp=[1,1,1,2,0,0,0,0]
dp=[1,1,1,2,2,0,0,0]
dp=[1,1,1,2,2,3,0,0]
dp=[1,1,1,2,2,3,4,0]
dp=[1,1,1,2,2,3,4,4]

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n=nums.size();
if(n==1) return 1;
vector<int> dp(n,0);
dp[0]=1;
for(int i=1;i<n;i++){
int maxLen=0;
for(int j=0;j<i;j++){
if(nums[j]<nums[i]){
maxLen=max(maxLen,dp[j]);
}
}
dp[i]=maxLen+1;
}
int res=1;
for(int i=0;i<n;i++){
res=max(res,dp[i]);
}
return res;
}
};
-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道