lc300.java 1.9 KB
Newer Older
L
liu13 已提交
1 2 3 4 5 6 7 8
package code;
/*
 * 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:经典题目,记一下
L
liu13 已提交
9
 *      lc132
L
liu13 已提交
10 11 12 13 14 15 16 17
 */
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]结尾的最大长度
L
liu13 已提交
18
        Arrays.fill(dp,1);  //记住fill 1
L
liu13 已提交
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
        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;
L
liu13 已提交
41 42
                if(dp[mid]<nums[i]) left = mid+1;   //这是+1记住,不能到else去-1, 会死循环。+1就超出边界,后续用left赋值
                else right = mid;
L
liu13 已提交
43 44 45 46 47 48 49
            }
            dp[left] = nums[i];
            if(left==size) size++;
        }
        return size;
    }
}