最长递增子序列

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值