一个序列a[]={1,7,3,5,9,4,8},找出它的最长上升子序列的个数,很明显是4个,可以是{1,3,5,9},{1,3,5,8}或者{1,3,4,8}。他有两种实现的方法:
第一种是时间复杂度为O(n^2)的算法:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
int main()
{//用数组b[N]来存放每个数的上升子序列的个数
int a[]={1,7,3,5,9,4,8};
int n=sizeof(a)/sizeof(int);
int b[sizeof(a)/sizeof(int)];
b[0]=1;
for(int i=1;i<n;i++)
{
b[i]=1;
for(int j=0;j<i;j++)
{
if(a[i]>a[j]&&b[j]+1>b[i])
b[i]=b[j]+1;
}
}
int maxb=0;
for(int i=0;i<n;i++)
{
if(maxb<b[i])
maxb=b[i];//找出b[N]的最大值
}
cout << maxb << endl;
return 0;
}
---------------------------------------------------------------------
第二种是时间复杂度为O(nlogn)的算法:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int check(int &it,int *a,int l,int r)
{用二分法来查找当前数字应该放的位置
while(l<r)
{
int mid=(l+r)/2;
if(it>a[mid]&&it<=a[mid+1])
return mid;
else if(it<a[mid])
r=mid-1;
else
l=mid+1;
}
}
int main()
{
int a[]={1,7,3,5,9,4,8};
int b[sizeof(a)/sizeof(int)];
int n=sizeof(a)/sizeof(int);
b[0]=a[0];
int len=1;
int j=0;
for(int i=1;i<n;i++)
{
if(a[i]>b[len-1])
j=len++;
else
j=check(a[i],b,0,len-1)+1;
b[j]=a[i];///用b[N]来记录最大子序列
}
cout << len << endl;
for(int i=0;i<len;i++)
{
cout << b[i] << " ";
}
return 0;
}