最长递增子序列

问题描述:给定一个数组a[a1,a2,a2......an],求它的最长递增的子数组长度。子数组是指该数组里的元素在位置的前后关系上保持原数组的关系。

最朴素的思想:求出以数组中每一个位置结尾的的最长递增子序列,选择其中的最大值,时间复杂度为O(n*n)。

现在有一种更巧妙的思想可以将时间复杂度变为O(n*logn),一看到logn我们很容易想到二分,使用二分的前提条件是有序,那么如何能够达到有序呢?

最长递增子序列O(n*logn)解法:首先开一个辅助数组h,长度和a数组相同,从a数组的第一个位置开始遍历,当前位置下标为i,在辅助数组h中去找第一个大于a[i]的数,用a[i]替换;如果h中没有大于a[i]的数,则将a[i]依次放在h数组中,这样我们保证了h数组中的数是有序的,可以使用二分查找,遍历一遍,h数组中保存的数的个数就是数组a的最长递增子序列长度。

	private static int arrUp(int[] a) {
		int[] h = new int[a.length];
		h[0] = a[0];// 初始h[0]的值为a[0]
		int length = 0;// 记录h数组中当前的下标
		int l = 0;
		int r = length;
		for (int i = 0; i < a.length; i++) {
			l = 0;
			r = length;
			while (l <= r) {
				int mid = (l + r) / 2;
				if (h[mid] < a[i]) {
					l = mid + 1;
				} else {
					r = mid - 1;
				}
			}
			length = Math.max(l, length);// 更新标记位置
			h[l] = a[i];// 将找到的位置替换为a[i]
		}
		// 数组从0开始,下标+1为其长度
		return length + 1;
	}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值