LIS longest Increasing subarray 最长递增子序列

    对于前面i个元素的任何一个递增子序列,如果这个子序列的最大的元素比array[i+1]小,那么就可以将array[i+1]加在这个子序列后面,构成一个新的递增子序列。

    比如当i=4的时候,目标序列为:1,-1,2,-3,4,-5,6,-7最长递增序列为:(1, 2),(-1, 2)。那么,只要4>2,就可以把4直接增加到前面的子序列形成一个新的递增子序列。因此,我们希望找到前i个元素中的一个递增子序列,使得这个递增子序列的最大的元素比array[i+1]小,且长度尽量地长。这样将array[i+1]加在该递增子序列后,便可找到以array[i+1]为最大元素的最长递增子序列。

    假设在数组的前i个元素中,以array[i]为最大元素的最长递增子序列的长度为lis[i]。

    同时,假设:

    长度为1的递增子序列最大元素的最小值为maxv[1];

    长度为2的递增子序列最大元素的最小值为maxv[2];

     ......

     长度为lis[i]的递增子序列最大元素的最小值为maxv[lis[i]]。

     假如维护了这些值,那么,在算法中就可以利用相关的信息来减少判断的次数。

代码如下:

	public int longestIncresingSubarray(int[] arr) {
		if(null == arr || 0 == arr.length) {
			return 0;
		}
		int len= arr.length;
		int[] maxv = new int[len+1];
		int[] lis = new int[len];
		maxv[0] = Integer.MIN_VALUE;
		maxv[1] = arr[0]; // 长度 1 的最长子序列中,最后一个数的最小值
		
		// init
		for(int i=0; i<len; ++i) {
			lis[i] = 1;
		}
		
		int nMaxLis = 1; // 当前最长递增子序列长度
		for(int i=1; i<len; ++i) {
			int j = nMaxLis;
			// 更新lis, j指向更新的maxv, 即长度为j的maxv
			while(j >= 0) {
				if(arr[i] > maxv[j]) {
					lis[i] = j+1;
					break;
				}
				--j;
			}
			
			//如果找到更长的最长递增子序列
			if(lis[i] > nMaxLis) {
				nMaxLis = lis[i];
				maxv[lis[i]] = arr[i];
			} else if(maxv[j] < arr[i] && maxv[j+1] > arr[i] ) {
				maxv[j+1] = arr[i];
			}
		}
		return nMaxLis;
	}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值