最长递增子序列

来源:互联网 发布:nginx hls 配置 编辑:程序博客网 时间:2024/05/16 05:14

这道题是编程之美的2.16.


这里


编程之美在用DP讲的时候思路还是比较清晰的。时间复杂度为 N^2,看下代码;

public int list(int[] A){int sum = 0;int[] LIS = new int[A.length];for(int i=0;i<A.length;i++){LIS[i]=1;for(int j=0;j<=i;j++){if(A[i]>A[j]&&(LIS[j]+1>LIS[i])){LIS[i]=LIS[j]+1;}}}for(int i:LIS){System.out.print(" "+i);sum=Math.max(sum, i);}System.out.println();return sum;}




但是在用NlongN的方法时,讲的人头晕的不行。网上搜了下别人的讲解,秒懂~


具体做法如下:

开一个栈,每次取栈顶元素top和读到的元素temp做比较,如果temp > top 则将temp入栈;如果temp < top则二分查找栈中的比temp大的第1个数,并用temp替换它。

最长序列长度即为栈的大小top。(这里的栈可以用一个数组直接处理。用栈解释比较容易理解)

例子:  1,-1,2,-3,4,-5,6,-7

第一步: 栈为1

第二步:发现-1<1,替换掉1,栈为-1

第三步:2>-1,栈中为 -1 ,2

第四步:找到大于-3的第一个数字替换 ,栈为 -3,2

第四步:4>2,入栈,此时为  -3,2,4

接下来如上。。

最后为-7,2,4,5

长度为4~~

public int lis(int[] A){int[] LIS = new int[A.length];LIS[0]=A[0];int position=0;for(int i=1;i<A.length;i++){if(A[i]>LIS[position])replace(A[i],LIS,0,position);else{LIS[++position]=A[i];}}return position;}public void replace(int target,int[] LIS,int start,int position){System.out.println(" "+position);int end=position;int mid = (start+end)/2;if(position==0)LIS[0]=target;if(LIS[mid]<target ){if(mid+1<position){//满足条件,替换if(LIS[mid+1]>target)LIS[mid+1]=target;else if(LIS[mid+1]<target)replace(target, LIS, mid+1, position);}}if(LIS[mid]>target){replace(target,LIS,0,mid-1);}if(LIS[mid]==target)return;}


0 0