最长递增子序列(编程之美)

public class TheLargestIncreamentSubSequnece {
	public static void main(String[] args) {
		 int a[]={1,-1,2,-3,4,-5,6,-7};
		//int a[] = { 1, -5, -4, 2, 3, 4, 5, 6, -3, -2, -1, 2, 3 };
		// System.out.println(theLargestIncreamentSubSequence(a));
		System.out.println(theLargestIS(a));
	}

	private static int theLargestIS(int[] a) {
		// TODO Auto-generated method stub
		int low, high, mid;
		int LIS[] = new int[a.length];//存放最大递增子序列的最末元素
		LIS[0] = -100000;// 把LIS[0]设为最小假设数组中的数都大于LIS[0];
		LIS[1] = a[0];//初始时,最大递增子序列长度为1的最末元素为a1
		int len = 1;//最长递增子数组的初始长度
		
		for (int i = 1; i < a.length; i++) {
			low = 0;
			high = len;
			/*
			 * 在第二种算法中,在计算每一个f(i)时,都要找出最大的f(j)(j<i)来,由于f(j)没有顺序,
			 * 只能顺序查找满足aj<ai最大的f(j),如果能将让f(j)有序,就可以使用二分查找,
			 * 这样算法的时间复杂度就可能降到O(nlogn)。于是想到用一个数组B来存储“子序列的”最大递增子序列的最末元素,
			 * 即有
				B[f(j)] = aj
				在计算f(i)时,在数组B中用二分查找法找到满足j<i且B[f(j)]=aj<ai的最大的j,
				并将B[f[j]+1]置为ai
			 */
			while (low <= high) {//二分查找最末元素小于ai+1的长度最大的最大递增子序列;
				
				mid = (low + high) >> 1;
				if (LIS[mid] < a[i])
					low = mid + 1;
				else {
					high = mid-1;
				}
				
			}
			LIS[low]=a[i];//将长度为p的最大递增子序列的当前最末元素置为ai+1;
			if(low>len)len++;//更新当前最大递增子序列长度;
		}
		for(int i=0;i<LIS.length;i++)
		{
			System.out.print(LIS[i]+"  ");
		}
		System.out.println();
		for(int i=1;i<=len;i++)
		{
			System.out.print(LIS[i]+"  ");
		}
		System.out.println();//时间复杂度为O(Nloglen);
		return len;
	}

	private static int theLargestIncreamentSubSequence(int[] a) {
		// TODO Auto-generated method stub
		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;
				}
			}
		}
		int max = LIS[0];
		for (int i = 1; i < LIS.length; i++) {
			if (LIS[i] > max) {
				max = LIS[i];
			}
		}
		return max;
	}
//时间复杂度为O(n^2)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值