1. 程式人生 > >最長遞增子序列,時間複雜度(O(nlogn))

最長遞增子序列,時間複雜度(O(nlogn))

package com.kailong.datastures;

import java.util.Arrays;

/**
 * Created by Administrator on 2017/4/17.
 * 最長遞增子序列
 */
public class FindMaxIntLong {
    public static int[] getList1(int []arr){
        if(arr==null||arr.length==0){
            return null;
        }
        int []dp=getdp1(arr);
        System.out.println(Arrays.toString(dp));
        return generateLIS(arr,dp);
    }

    private 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;
    }

    private static int[] getdp1(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;
    }
    private static int [] getdp2(int []arr){
        int[] dp=new int[arr.length];
        int [] ends=new int[arr.length];
        ends[0]=arr[0];
        dp[0]=1;
        int right=0,l=0,r=0,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;
    }
    private static int[] getList2(int[] arr) {
        if(arr==null||arr.length==0){
            return null;
        }
        int []dp=getdp2(arr);
        System.out.println(Arrays.toString(dp));
        return generateLIS(arr,dp);
    }
    public static void main(String []args){
        int [] ss={2,3,6,3,7,2,7,9,4,0,1,34,56,3,0,2,2,2,4,77,84,3838,2,288,1727,16,67,2,87282,8228,22,82,2,81,8,34,5,8};
        int[] result1 = getList1(ss);
        int []result2=getList2(ss);
        System.out.println(Arrays.toString(result1));
        System.out.println(Arrays.toString(result2));
    }
}