求数组中最长递增子序列:
求一个一维数组中最长递增子序列的长度?
例如:
1,-1,2,-3, 4,-5 ,6,-7;
其最长递增子序列的长度为4( 1, 2 ,4 ,6 );
一下是我根据“编程之美” 的解法三的实现代码.供大家参考:
#include<iostream>
#include <assert.h>
using namespace std;
const int Inf=1000000;
int MyMin(int *data,int n)
{
if (data==NULL||n<0)
{
return -Inf;
}
int min=data[0];
for (int i=0;i<n;i++)
{
if (min>data[i])
{
min=data[i];
}
}
return min;
}
int MyMax(int *data,int n)
{
if (data==NULL||n<0)
{
return -Inf;
}
int max=data[0];
for (int i=0;i<n;i++)
{
if (max<data[i])
{
max=data[i];
}
}
return max;
}
int SeachLongest(int *Maxdata,int low,int high,int num)
{
if (Maxdata==NULL||low>high)
{
return -1;
}
int mid;
while (low<=high)
{
mid=(low+high)/2;
if (Maxdata[mid]==num)
{
return mid-1;
}
else if (Maxdata[mid]>num)
{
if (low==high)
{
return mid-1;
}
high=mid-1;
}
else
{
if (low==high)
{
return mid;
}
low=mid+1;
}
}
return high;
}
/*总共 n 个元素*/
int LongestSubSequence(int *data,int n)
{
/*List[i] 表示 带第i 个元素时最长子序列的长度*/
int *List=new int[n];
/*
MaxV 【j】表示 长度为j的子序列的最大元素的最小值
长度为j的子序列可能有好几个 他们的最右端的元素即
为他们的最大值 而我们需要最小的那个
*/
/*
由MaxV 定义可以知道 该数组是递增的; 长度为j+1 的子序列是有长度为 j 的子序列(注意子序列为递增序列)
通过添加元素得来的
故 MaxV[j+1]>MaxV[j]
*/
int *MaxV=new int[n+1];
MaxV[0]=MyMin(data,n)-1;//比data 的所有值都小
List[0]=1;
int maxlen=1;
MaxV[1]=data[0];
for (int i=1;i<=n;i++)/*遍历所有元素 */
{
List[i]=1;
int j=SeachLongest(MaxV,0,maxlen,data[i]);
assert(j>=0&&j<=n);
/*
j 是满足MaxV[K]<data[i] 的最大 k 值,
由于MaxV[ ] 是单调递增的故可以采用二分搜索
时间复杂度为 log(n)
*/
List[i]=j+1;
if (List[i]>maxlen)
{
maxlen=List[i];
MaxV[maxlen]=data[i];
}
else if (MaxV[List[i]]>data[i])
{
MaxV[List[i]]=data[i];
}
}
return MyMax(List,n);
}
int main()
{
int data[7]={1,2,3,24,5,6,7};
cout<<LongestSubSequence(data,7)<<endl;
return 0;
}