最长递增子序列
思路:记录到第i个元素时的最长递增序列数组的结尾元素,因为递增序列结尾元素数组一定有序,所以计算第i+1个元素时,可以二分查找以其结尾的最长递增序列的位置即可。时间复杂度为O(NlogN)
int LIS(int a[],int n)
{
assert(a!=NULL&&n>0);
vector<int> LastElement(n+1);
int len=1;
LastElement(0)=numeric_limits<int>::min();//哨兵位
LastElement(1)=a[0];
for(int i=1;i<n;i++)
{
int p=0;
int r=len;
while(p<=r)
{
int m=(r+p)/2;
if(LastElement(m)<a[i])
p=m+1;
else
r=m-1;
}
LastElement(p)=a[i];//p所在位置即为以a[i]为尾时的最长序列长度,且a[i]一定是目前该长度的最小结尾元素
if(p>len)p=len+1;
}
return len;
}
思路二:可以转为求最长公共子序列,用另外一个数组存放原数组排序后的序列,然后求两者的LCS即可,时间复杂度为O(N2);