最长递增子序列
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; }