Given an unsorted array of integers, find the length of longest increasing subsequence.
问题描述:返回所给乱序数组中的最长递增序列的长度For example,
Given [10, 9, 2, 5, 3, 7, 101, 18],
The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4
题目链接:链接
本周算法分析课程提到最长递增序列的动态规划问题,课后及时巩固学习;
解题思路:
solution1: 维护一个长度为n的数组,一一对应地记录乱序数组中以该index结尾的递增序列的长度,时间复杂度为O(n^2)。
int lengthOfLIS(vector<int>& nums) {
int n = nums.size();
//序列最短为1
vector<int> v(n, 1);
for(int i = 1; i < n; i++){
for(int j = 0; j < i; j++){
if(nums[i] > nums[j]){
v[i] = max(v[i], v[j] + 1);
}
}
}
int res = 0;
for(int i = 0;i < n; i++){
res = max(res, v[i]);
}
return res;
}
solution2: 维护一个包含与最长递增序列等长的数组,若扫描的整数大于数组中最大值(末位),将整数加入数组末尾,否则用整数更新该递增序列;
int lengthOfLIS(vector<int>& nums) {
int n = nums.size();
if(n < 2) return n;
vector<int> res;
res.push_back(nums[0]);
for(int i = 1; i < n; i++){
if(nums[i] > res.back()){
res.push_back(nums[i]);
} else {
if(nums[i] < res[0]) res[0] = nums[i];
else
for(int j = res.size() - 1; j > -1; j--){
if(nums[i] > res[j]){
res[j + 1] = nums[i];
break;
}
}
}
}
return res.size();
}
学习solution,发现STL中有std::lower_bound(vec.begin(), vec.end(), val)方法,函数返回vector中大于该元素的最小值的迭代器,解题更加简洁;
int lengthOfLIS(vector<int>& nums) {
vector<int> res;
for(int i=0; i<nums.size(); i++) {
auto it = std::lower_bound(res.begin(), res.end(), nums[i]);
if(it==res.end()) res.push_back(nums[i]);
else *it = nums[i];
}
return res.size();
}
拓展:
lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)
:算法返回一个非递减序列[first, last)中的第一个大于等于值val的位置;
upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)
:算法返回一个非递减序列[first, last)中第一个大于val的位置。