zoukankan      html  css  js  c++  java
  • leecode 300. 最长递增子序列

    /*
     * 300. Longest Increasing Subsequence
     * 题意:最长递增子数组,不一定是连续的
     * 难度:Medium
     * 分类:Binary Search, Dynamic Programming
     * 思路:基本的思路是dp[i]记录以nums[i]结尾的最长长度,每次遍历 dp[i] 得到dp[i+1],复杂度为O(n^2)。最优的解法是O(nlgn),dp[i]是递增的数组,每次插入时二分查找是lgn。
     * Tips:经典题目,记一下
     *      lc132
     */
    import java.util.Arrays;
    
    public class lc300 {
        public int lengthOfLIS(int[] nums) {
            if(nums.length<2)
                return nums.length;
            int[] dp = new int[nums.length]; //dp[i] 存储以nums[i]结尾的最大长度
            Arrays.fill(dp,1);  //记住fill 1
            int res = 1;
            for (int i = 1; i < nums.length ; i++) {
                for (int j = 0; j < i ; j++) {
                    if(nums[i]>nums[j]){
                        dp[i] = Math.max(dp[j]+1, dp[i]);
                    }
                }
                res = Math.max(res, dp[i]);
            }
            return res;
        }
    
        public int lengthOfLIS2(int[] nums) {
            if(nums.length<2)
                return nums.length;
            int size = 0;   //size指dp中递增的长度。  dp[0~i] 表示了长度为 i+1 的递增子数组,且最后一个值是最小值
            int[] dp = new int[nums.length];    //dp存储递增的数组,之后更新这个数组。如果x>最后一个值,则插入到末尾,否则更新对应位置上的值为该值。
            for (int i = 0; i < nums.length ; i++) {
                int left = 0;
                int right = size;
                while(left!=right){ //得到要插入的位置
                    int mid = (left+right)/2;
                    if(dp[mid]<nums[i]) left = mid+1;   //这是+1记住,不能到else去-1, 会死循环。+1就超出边界,后续用left赋值
                    else right = mid;
                }
                dp[left] = nums[i];
                if(left==size) size++;
            }
            return size;
        }
    }
  • 相关阅读:
    Java打jar包详解
    用户体验评价
    本周总结(13)
    本周总结(12)
    第一阶段意见评论
    本周总结(11)
    冲刺计划第十天
    冲刺计划第九天
    冲刺计划第八天
    冲刺计划第七天
  • 原文地址:https://www.cnblogs.com/kpwong/p/14658118.html
Copyright © 2011-2022 走看看