問題:對於一個一維數組,求這個一維數組中的最長遞增子序列的長度。
例如:如果一維數組為{1,-1,2,-3,4,-5,6,-7},則得到的一個最長遞增子序列為{1,2,4,7},長度為4。
下面是java語言編寫的兩種實現方法。
package com.application.sample;import java.util.Arrays;//求一個序列的最長遞增子序列public class LISsample {public static void main(String[] args) {// TODO Auto-generated method stubint[] arr={1,4,2,3,5,8,7};long start=System.nanoTime();System.out.println("長度為:"+lis1(arr));long end=System.nanoTime();System.out.println("用時:"+(end-start)+"納秒");start=System.nanoTime();System.out.println("長度為:"+lis2(arr));end=System.nanoTime();System.out.println("用時:"+(end-start)+"納秒");start=System.nanoTime();System.out.println("長度為:"+lis3(arr));end=System.nanoTime();System.out.println("用時:"+(end-start)+"納秒");}public static int lis1(int[] array){if(array==null||array.length==0)return -1;int len=array.length;int[] lis=new int[len];for(int i=0;i<len;i++){lis[i]=1;for(int j=0;j<i;j++){if(array[j]<array[i]&&(lis[j]+1)>lis[i]){lis[i]=lis[j]+1;}}}System.out.println(Arrays.toString(lis));return maxArray(lis);}public static int lis2(int[] array){if(array==null||array.length==0)return -1;int len=array.length;int[] lis=new int[len];int maxlength=1;int[] minV=new int[len+1];minV[0]=minArray(array)-1;minV[1]=array[0];Arrays.fill(lis, 1);for(int i=1;i<len;i++){int j;for(j=maxlength;j>=0;j--){if(array[i]>minV[j]){lis[i]=j+1;break;}}if(lis[i]>maxlength){maxlength=lis[i];minV[lis[i]]=array[i];}else if(minV[j]<array[i]&&array[i]<minV[j+1]){minV[j+1]=array[i];}}System.out.println(Arrays.toString(lis));return maxlength;}public static int lis3(int[] array){if(array==null||array.length==0)return -1;int len=array.length;int[] lis=new int[len];int maxlength=1;int[] minV=new int[len+1];minV[0]=minArray(array)-1;minV[1]=array[0];Arrays.fill(lis, 1);for(int i=1;i<len;i++){int j;for(j=lis[i-1];j>0;j--){if(array[i]>minV[j]){lis[i]=j+1;break;}}if(lis[i]>maxlength){maxlength=lis[i];minV[lis[i]]=array[i];}else if(minV[j]<array[i]&&array[i]<minV[j+1]){minV[j+1]=array[i];}}System.out.println(Arrays.toString(lis));return maxlength;}private static int minArray(int[] array){int result=array[0];for(int i=1;i<array.length;i++){if(array[i]<result)result=array[i];}return result;}private static int maxArray(int[] array){int result=array[0];for(int i=1;i<array.length;i++){if(array[i]>result)result=array[i];}return result;}}
運行結果如下所示:
[1, 2, 2, 3, 4, 5, 5]長度為:5用時:332238納秒[1, 2, 2, 3, 4, 5, 5]長度為:5用時:122968納秒[1, 2, 2, 3, 4, 5, 5]長度為:5用時:89809納秒
從運行結果來看,也驗證了在編程之美中關於這個問題的時間複雜度的分析。