给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],
它的长度是
4
说明:
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
n方做法:
dp[i]=max(dp[j]+1,dp[i]),
,
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
//定义 dp[i]dp[i] 为考虑前 ii 个元素,以第 ii 个数字结尾的最长上升子序列的长度,注意 \textit{nums}[i]nums[i] 必须被选取。
int dp[nums.size()+5];
for(int i=0;i<nums.size()+5;i++)dp[i]=1;
int maxx=1;
int k=nums.size();
if(!k)return 0;
for(int i=1;i<k;i++)
{
for(int j=i-1;j>=0;j--)
if(nums[i]>nums[j])dp[i]=max(dp[j]+1,dp[i]),maxx=max(maxx,dp[i]);
}
return maxx;
}
};
nlogn做法:
d[i]表示长度为i的末尾元素值,遍历一遍nums,遇到比当前d[len]元素大的就接在后面,否则就二分插入d[1~len]中的某个位置~
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int k=nums.size();
if(!k)return 0;
vector<int>d;
d.push_back(nums[0]);//表示长度i末尾元素值
int len=1;
for(int i=1;i<nums.size();i++)
{
if(nums[i]>d[len-1])d.push_back(nums[i]),len++;
else
{
*lower_bound(d.begin(),d.end(),nums[i])=nums[i];
}
}
return len;
}
};