这道题是编程之美的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;
}