题目描述:
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入:[10,9,2,5,3,7,101,18]
输出: 4 解释: 最长的上升子序列是[2,3,7,101],
它的长度是4
说明:
- 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
- 你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
算法1:
时间复杂度O(n^2)
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int>dp(nums.size(), 1);
if(nums.size() < 1)
return 0;
else
{
dp[0] = 1;
int Max = 1;
for(int i=1; i < nums.size(); i++)
{
for(int j=0; j<i; j++)
{
if(nums[i] > nums[j])
dp[i] = max(dp[i], dp[j]+1);
}
Max = max(dp[i], Max);
}
return Max;
}
}
};
算法2:
二分查找:时间复杂度O(nlogn)
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int>value;
for(int i=0; i<nums.size(); i++)
{
if(value.empty() || nums[i] > value.back())
value.push_back(nums[i]);
else
{
*lower_bound(value.begin(), value.end(), nums[i]) = nums[i];
}
}
return value.size();
}
};
自定义二分类函数的写法
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int>value;
for(int i=0; i<nums.size(); i++)
{
if(value.empty() || nums[i] > value.back())
value.push_back(nums[i]);
else
{
//*lower_bound(value.begin(), value.end(), nums[i]) = nums[i];
int index = binary(value, nums[i]);
value[index] = nums[i];
}
}
return value.size();
}
int binary(vector<int>& value, int target)
{
int left = 0, right = value.size()-1;
while(left < right)
{
int mid = (right-left) /2 + left;
if( target <= value[mid] )
{
right = mid;
}
else
left = mid +1;
}
return left;
}
};