LIS longest Increasing subarray 最长递增子序列

来源:互联网 发布:mac系统怎么制作铃声 编辑:程序博客网 时间:2024/06/05 20:20

    对于前面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 的最长子序列中,最后一个数的最小值// initfor(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的maxvwhile(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
原创粉丝点击