最长递增子序列

简介: 最长递增子序列

题目

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例 1:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-increasing-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

一、O(n^2^)的解

动态规划,从左到右模型
dp[i]子序列必须以i位置的数结尾的情况下,最长递增子序列是多长?整个中求max就是答案
每次求dp[i]时,遍历数组0到i-1,找出比nums[i]小的数的位置j,
dp[i]=Math.max(dp[i],dp[j]+1);

代码

class Solution {
    public int lengthOfLIS(int[] nums) {
        int n=nums.length;
        if(n==0){
            return 0;
        }
        int max=1;
        int[] dp=new int[n];
        dp[0]=1;
        for(int i=1;i<n;i++){
            dp[i]=1;
            for(int j=0;j<i;j++){
                if(nums[i]>nums[j]){
                    dp[i]=Math.max(dp[i],dp[j]+1);
                }
            }
            max=Math.max(max,dp[i]);
        }
        return max;
    }
}

最优解

辅助end数组
end[i]:目前所有长度为i+ 1的递增子序列中的最小结尾

如何填写end?
每次遍历到一个数num[i],用二分在end数组中找到最左大于num[i]的位置j
end[j]=num[i];
如果没有大于num[i]的数,则end[j+1]=num[i]
你把一个值塞进去之后,改写的位置含义是对的,没改写的位置继续保证正确的含义

    public static int lengthOfLIS(int[] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        int[] ends = new int[arr.length];
        ends[0] = arr[0];
        int right = 0;
        int l = 0;
        int r = 0;
        int m = 0;
        int max = 1;
        for (int i = 1; i < arr.length; i++) {
            l = 0;
            r = right;
            while (l <= r) {
                m = (l + r) / 2;
                if (arr[i] > ends[m]) {
                    l = m + 1;
                } else {
                    r = m - 1;
                }
            }
            right = Math.max(right, l);
            ends[l] = arr[i];
            max = Math.max(max, l + 1);
        }
        return max;
    }
相关文章
|
9月前
|
算法 JavaScript Go
【动态规划】最长递增子序列
【动态规划】最长递增子序列
|
1月前
leetcode-300:最长递增子序列
leetcode-300:最长递增子序列
28 0
|
1月前
leetcode-1143:最长公共子序列
leetcode-1143:最长公共子序列
37 0
|
8月前
|
算法
【学会动态规划】 最长递增子序列(26)
【学会动态规划】 最长递增子序列(26)
24 0
|
8月前
|
算法
【学会动态规划】最长递增子序列的个数(28)
【学会动态规划】最长递增子序列的个数(28)
24 0
|
11月前
1265:【例9.9】最长公共子序列 2021-01-15
1265:【例9.9】最长公共子序列 2021-01-15
leetcode 300 最长递增子序列
leetcode 300 最长递增子序列
66 0
leetcode 300 最长递增子序列
leetcode 1143 最长的公共子序列
leetcode 1143 最长的公共子序列
76 0
leetcode 1143 最长的公共子序列
|
算法 Python
LeetCode 300. 最长递增子序列
最长递增子序列 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
103 0