LIS-最长递增子序列的长度-java

LIS序列不要求连续,查看资料发现一般有两种时间复杂度的算法,分别是O(n^2)和O(n*log n),下面分析的是复杂度为 O(n^2)的算法:
dp[i]表示以a[i]结尾的所有子序列中符合原则——递增不减的序列(因为符合条件的还是有很多序列的)中的最长长度,对于每一个a[i],有一个子序列只包括自己,故a[i]的最长递增子序列长度的最小值是1。

思路分析:
有数组arr[1…n],设最长递增子序列的长度为dp,发现dp与变量i相关,故需要分析变量dp[i]的意义

    1. 若有a[i]>a[j] (j属于0...i-1)则有子序列:以a[i]结尾,还包括a[j],则这样的子序列的长度为以a[j]结尾的递增子序列的最大长度+1(因为前面提到a[i]的最长递增子序列长度的最小值是1),即dp[i]=dp[j]+1;

    2. 对于j属于0...i-1中的某一个值,若a[i]<a[j],则dp[i]=1;

    3. 遍历数组dp[i] (i属于0...arr.length-1), 找出最大值,该最大值就是该给定序列的最长递增子序列的长度
public class LIS {
    public static void main(String[] args) {
        // int[] arr = {9, -8,-1, 6, 7,-2, 0};
        int[] arr = { 9, -8, -1, 6, 5, -2, 0 };
        // solution(arr);
        solution3(arr);
    }

    public static void solution3(int[] arr) {
        int[] dp = new int[arr.length];
        dp[0] = 1;
        for (int i = 1; i < arr.length; i++) {
            for (int j = 0; j < i; j++) {
                if (arr[i] > arr[j]) {
                    dp[i] = dp[j] + 1;
                } else {
                    dp[i] = 1;
                }

            }
        }
        int maxLength = 0;
        for (int i = 0; i < dp.length; i++) {
            if (dp[i] > maxLength) {
                maxLength = dp[i];
            }

        }
        System.out.println(maxLength);
    }

    public static void solution2(int[] arr) {
        int[] dp = new int[arr.length];
        dp[0] = 1;
        for (int i = 1; i < arr.length; i++) {
            int temp = 0;
            for (int j = 0; j < i; j++) {

                 if( (arr[i]>arr[j])){
                     if(temp<dp[j])
                     temp = dp[j];
                     }
                 }
                 dp[i] = temp+1;
            }

        int maxLength = 0;
        for (int i = 0; i < dp.length; i++) {
            if (dp[i] > maxLength) {
                maxLength = dp[i];
            }
        }
        System.out.println(maxLength);
    }

    public static void solution1(int[] arr) {
        int[] dp = new int[arr.length];
        dp[0] = 1;
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            // int max2 =arr[0];
            // for(int j = 0;j<i;j++){
            // if(arr[j]>max2){
            // max2= arr[j];
            // }
            // }\
            int temp = 0;
            for (int j = 0; j < i; j++) {

                if ((arr[i] > arr[j])) {
                    if (temp < dp[j])
                        // dp[i]=dp[i-1]+1;
                        temp = dp[j];
                }
                dp[i] = temp + 1;
                // }else{
                // dp[i] = dp[i-1];
                // }
            }
            // if(arr[i]>max){
            // max = arr[i];
            // dp[i]=dp[i-1]+1;
            //
            // }else{
            // dp[i] = dp[i-1];
            // }
        }
        int maxLength = 0;
        for (int i = 0; i < dp.length; i++) {
            if (dp[i] > maxLength) {
                maxLength = dp[i];
            }
        }
        System.out.println("maxLength: " + maxLength);

    }

    public static void solution(int[] arr) {
        int[] dp = new int[arr.length];
        dp[0] = 1;
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
                dp[i] = dp[i - 1] + 1;

            } else {
                dp[i] = dp[i - 1];
            }
        }
        int maxLength = 0;
        for (int i = 0; i < dp.length; i++) {
            if (dp[i] > maxLength) {
                maxLength = dp[i];
            }
        }
        System.out.println("maxLength: " + maxLength);
    }

}

上面的solution2方法和solution3方法是完整的解决方案,其他的方法也是可以参考得,对于理清思路很有帮助

Reference:
1. http://blog.csdn.net/sdjzping/article/details/8759870
2. http://blog.chinaunix.net/uid-28311809-id-4251024.html
3. http://www.cnblogs.com/handsomecui/p/4692350.html
4. http://blog.163.com/zhaohai_1988/blog/static/20951008520127923814649/
5. http://www.cnblogs.com/pblr/p/5718875.html
6. http://www.cnblogs.com/waytofall/archive/2012/09/10/2678576.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值