最长上升子序列

来源:互联网 发布:撒谎眼睛往哪看 知乎 编辑:程序博客网 时间:2024/06/13 22:20

广场上站着一支队伍,她们是来自全国各地的扭秧歌代表队,现在有她们的身高数据,请你帮忙找出身高依次递增的子序列。
例如队伍的身高数据是(1、7、3、5、9、4、8),其中依次递增的子序列有(1、7),(1、3、5、9),(1、3、4、8)等,其中最长的长度为4。

方法一:

/* * 时间复杂度O(n^2) */public class LongIncrementSequence {    public static void main(String[] args) {        int[] arr = {1,7,3,5,8,9};        System.out.println(LongIncrementSequence.getLongIncrementSequence(arr));    }    public static int getLongIncrementSequence(int[] array){        /*         * result 返回最长递增子序列长度         */        int result = 1;        int len = array.length;        int[] dp = new int[len];        dp[0] = 1;        /*         * dp[i] = Max(dp[j])+1   (1<=j<i)         */        for(int i = 1;i<len;i++){            /*             *  max = Max(dp[j])             *               */            int max = 0;            for(int j = 0;j<i;j++){                if(dp[j]>max&&array[j]<array[i]){                    max = dp[j];                }            }            dp[i] = max+1;            if(dp[i]>result){                result = dp[i];            }        }        return result;    }}

方法二

/** *  * @author 过路的守望 * 改进后的计算最长上升子序列的算法时间复杂度为O(NlogN),增加了一个辅助数组help。 * help用来保存之前的最长上升子序列。 * */public class LongIncrementSequenceImproved {    public static void main(String[] args) {        int[] arr = { 1, 3, 8, 5, 4, 6, 7, 4, 9 };        System.out.println(LongIncrementSequenceImproved                .getLongIncrementSequence(arr));    }    public static int getLongIncrementSequence(int[] arr) {        int len = arr.length;        /*         * dp[i]记录i位置的最长子序列长度         */        int[] dp = new int[len];        int[] help = new int[len];        /*         * size记录当前help数组中的最后一个数据的下标         */        int size = 0;        int j = 0;        /*         * i为0时,dp[0]显然为1。         */        dp[0] = 1;        /*         * help[0]的初始值为arr[0]         */        help[0] = arr[0];        for (int i = 1; i < len; i++) {            if (arr[i] < help[0]) {                j = 0;            } else if (arr[i] > help[size]) {                j = ++size;            } else {                j = binarySearch(help, arr[i], size);            }            dp[i] = j + 1;            help[j] = arr[i];        }        return size+1;    }    /**     * 改进二分查找寻找当前目标值所处下标     * @param help     * 目标值     * @param target     * 当前数组中有效数据长度     * @param length     * @return     */    public static int binarySearch(int[] help, int target, int length) {        int low = 0;        int high = length;        int mid;        while (low <= high)            mid = (low + high) / 2;            if (target == help[mid]) {                return mid;            } else if (target > help[mid] && target < help[mid + 1]) {                return mid + 1;            } else if (target > help[mid]) {                low = mid + 1;            } else {                high = mid - 1;            }        return -1;    }}
0 0