最长递增子序列

来源:互联网 发布:javascript 观察者模式 编辑:程序博客网 时间:2024/06/14 00:41

//最长递增子序列public class getMaxLenSerial{//经典的方法获得最长子序列的长度public static int[]getdp01(int[]arr){int[]dp=new int [arr.length];for(int i=0;i<arr.length;i++){dp[i]=1;for(int j=0;j<i;j++){if(arr[i]>arr[j]){dp[i]=Math.max(dp[i],dp[j]+1);}}}return dp;}//逆序还原出决策路径public static int[]generateLIS(int[]arr,int[]dp){         int len=0;         int index=0;         for(int i=0;i<dp.length;i++)         {         if(dp[i]>len)         {         len=dp[i];         index=i;         }         }         int []lis=new int[len]; //存储返回的最长递增子序列         lis[--len]=arr[index];         for(int i=index;i>=0;i--)//逆序寻找         {         if(arr[i]<arr[index]&&dp[i]==dp[index]-1)         {         lis[--len]=arr[i];         index=i;         }         }         return lis;}//算法的主方法(时间复杂度为O(N*N))public static int[]list1(int[]arr){if(arr==null||arr.length==0){return null;}int[]dp=getdp01(arr);return generateLIS(arr,dp);}//********************************************************//二分查找获得dp数组public static int[]getdp02(int[]arr){int[]dp=new int[arr.length];int[]ends=new int[arr.length];ends[0]=arr[0];dp[0]=1;int right=0;int l=0;int r=0;int m=0;for(int i=1;i<arr.length;i++){l=0;r=right;//二分法while(l<=r){m=(l+r)/2;if(arr[i]>ends[m]){l=m+1;}else{r=m-1;}}right=Math.max(right,l);ends[l]=arr[i];dp[i]=l+1;}return dp;}    //方法二的主方法(O(NlogN))public static int[]list2(int []arr){if(arr==null||arr.length==0){return null;}int[]dp=getdp02(arr);return generateLIS(arr,dp);}//********************************************//打印序列的内容public static void printList(int[]lis){if(lis==null){return ;}for(int i=0;i<lis.length;i++){System.out.print(lis[i]+" ");}        System.out.println();}public static void main(String []args){//System.out.println("Hello");int[]arr={2,1,5,3,6,4,8,9,7};        printList(list1(arr));        printList(list2(arr));}}