300. 最长上升子序列
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
解题
设置数组tail,每一位存该位上最小的数;
从前往后遍历nums,每次找到当前nums应该在tail中的位置,插入即可;
end记录最长的序列距离;
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n =nums.size();
if(!n) return 0;
tail.resize(n,0);
int end=0;
for(auto num:nums){
int left=0;
int right=end; //end为右界,放在end'位置的数为当前最大值
while(left<right){
int mid=left+(right-left)/2;
if(tail[mid]<num) left=mid+1; //留小的
else right=mid;
}
tail[left]=num;
if(left==end) end++;
}
return end;
}
private:
vector<int> tail;
};
解释
只有遇到比end之前的数都大的数,新num才会添加到end,即left==end,此时end长度才会增加;
所以end保存了上升子序列的最大长度;