最长递增子序列

Q:求一个数组的最长递增子序列


A:数组为arr[n]

一个O(n^2)的算法

利用动态规划,利用一个辅助数组b[n],b[i]为对应以arr[i]结尾的最大递增子序列的长度,初始b[0]=1。从arr[1]到arr[n-1]的每次遍历中,设element=arr[i],考虑从当前索引i往前的所有索引j,如果element>arr[j],则当前element有可能扩展成一个新的递增子序列,在所有符合条件的arr[j]中,找出最大的b[j],即b[i]=b[j]+1。最后再遍历一边b数组,输出最大值,即代表最长递增子序列的长度。

 

 

一个O(nlogn)的算法

利用动态规划,考虑一个辅助数组b[n],b[i]代表长度为i的最长递增子序列末尾最小元素,则可以知道数组b是单调递增的,那么在遍历过程中利用二分查找,则可以判断当前元素可以比b数组中的哪个元素要小并且以前一个元素大,即可替代他作为更新后的最小元素,如果当前元素比b数组中的所有元素都要大,则将其插入b数组的最后,并且更新最长递增子序列的长度。

 

//定义b[n]为长度为i的最长递增子序列的末尾最小元素
#include <iostream>
using namespace std;
int Func(int* arr,int n)
{
	int *b=new int[n+1];
	int maxLen=1;
	b[1]=arr[0];
	for(int i=1;i<n;++i)
	{
		int left=1,right=maxLen;
		while(left<=right)
		{
			int mid=(left+right)/2;
			if(b[mid]>arr[i])
				right=mid-1;
			else
				left=mid+1;
		}
		b[left]=arr[i];
		if(left>maxLen)
			maxLen=left;
	}
	return maxLen;	
}

int main()
{
	int arr[]={2,1,5,3,6,4,8,9,7};
	cout <<Func(arr,9)<<endl;
	return 0;
}
posted @ 2012-07-16 14:49  Cavia  阅读(331)  评论(0编辑  收藏  举报