给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
题目链接
1、动态规划
复杂度O(n^2)
#include<iostream>
using namespace std;
int arr[10000];
int _max=0;
int help[10000];//辅助空间,保存对应数组元素的最长递增子序列
int main()
{
int n;//数字个数
cin>>n;
for(int i=0;i<n;i++)
cin>>arr[i];
fill(help,help+n,1);//将辅助空间置1
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(arr[i]>arr[j])
{
help[i]=max(help[j]+1,help[i]);//当前元素的最长递增子序列的长度
}
}
}
for(int i=0;i<n;i++)
{
_max=max(_max,help[i]);//统计最长递增子序列
}
cout<<_max<<endl;
return 0;
}
2、贪心+二分
复杂度O(n*log(n))
#include<iostream>
#include<algorithm>
using namespace std;
int arr[10000];
int _max=0;
int INF=0x3f3f3f;//极大值
int last[10000];//辅助空间,存放递增子序列长度为当前下标+1的最小元素
int help[10000];//辅助空间,保存对应数组元素的最长递增子序列
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>arr[i];
fill(last,last+n,INF);
for(int i=0;i<n;i++)
{
int index=lower_bound(last,last+n,arr[i])-last;//查找位置
help[i]=index+1;
if(_max<help[i])
_max=help[i];
last[index]=arr[i];//如果数组当前位置元素比当前元素小被覆盖
}
cout<<_max<<endl;
return 0;
}