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
示例
输入:nums = [7,7,7,7,7,7,7]
输出:1
提示信息
1 <= nums.length <= 2500
− 1 0 4 < = n u m s [ i ] < = 1 0 4 -10^4 <= nums[i] <= 10^4 −104<=nums[i]<=104
题解1(C++版本)
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int ans = 0;
int dp[nums.size() + 1]; // dp[i]表示第i个元素结尾的最长严格递增子序列的长度
for(int i = 0; i < nums.size(); i++){
dp[i] = 1;
for(int j = 0; j < i; j++){
if(nums[j] < nums[i]) dp[i] = max(dp[i], dp[j] + 1);
}
}
for(int i = 0; i < nums.size(); i++){
ans = max(ans, dp[i]);
}
return ans;
}
};
题解2(C++版本)
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int ans = 1;
int dp[nums.size() + 1];
dp[1] = nums[0];
for(int i = 0; i < nums.size(); i++){
if(nums[i] > dp[ans]) dp[++ans] = nums[i];
else {
int L = 0, R = ans + 1, mid;
while(L + 1 < R){ // 二分答案
mid = (L + R)/2;
if(dp[mid] >= nums[i]) R = mid; // R返回数组dp中元素>=nums[i]的最小下标
else L = mid;
}
dp[R] = nums[i];
}
}
return ans;
}
};