300. 最长上升子序列(动态规划,二分查找)

 方法一: 动态规划 (O(n))

class Solution {
    public int lengthOfLIS(int[] nums) {
        int n = nums.length;
        if(n < 2) return n;
        int[] dp = new int[n+1]; // dp[i] : 以第i个数字结束的最长子序列长度
        int res = 0;
        for(int i = 1; i <= n; i++) {
            dp[i] = 1;
            for(int j = i-2; j >= 0; j--) {
                if(nums[i-1] > nums[j]) {
                    dp[i] = Math.max(dp[i],dp[j+1]+1);
                }
            }
            res = Math.max(res,dp[i]);
        }
        return res;
    } 
}

方法二: 二分查找(O(n log n))

class Solution {
    public int lengthOfLIS(int[] nums) {
        int n = nums.length;
        int[] arr = new int[n];
        int len = 0, res = 0; // len记录长度
        for(int num : nums) {
            int l = 0, r = len - 1;
            while(l <= r) {  // 每次遍历到一个值,插入arr数组第一个大于它的位置,更新长度
                int mid = (l + r) >> 1;
                if(arr[mid] >= num) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            }
            if(l == len) len++; // 表示长度增加
            arr[l] = num;
            res = Math.max(res,len);// 每次记录最大长度
        }
        return res;
    }
}
原文地址:https://www.cnblogs.com/yonezu/p/13266118.html