leetcode300 最长上升子序列(Medium)

Posted 人生苦短,及时刷题

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode300 最长上升子序列(Medium)相关的知识,希望对你有一定的参考价值。

题目来源:leetcode300 最长上升子序列

题目描述:

给定一个无序的整数数组,找到其中最长上升子序列的长度。

示例:

输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是?[2,3,7,101],它的长度是 4。
说明:

可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为?O(n^2) 。
进阶: 你能将算法的时间复杂度降低到?O(n log n) 吗?

解题思路:

动态规划,时间复杂度O(n^2),见代码。

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if(nums.empty()) return 0;
        int ans=1;
        vector<int> dp(nums.size(),0);//dp[i]表示以nums[i]结尾的前i个字符的最长子序列长度。
        dp[0]=1;
        for(int i=1;i<nums.size();i++){
            int maxVal=0;
            for(int j=0;j<i;j++){
                //必须满足nums[j]<nums[i],才能以nums[i]结尾,在所有满足条件中找出最大的
                if(nums[j]<nums[i]){
                    maxVal=max(dp[j],maxVal);
                }
            }
            dp[i]=maxVal+1;//长度+1
            ans=max(ans,dp[i]);//更新结果
        }
        return ans;
    }
};

复杂度降低到?O(n log n) ,可以使用贪心+二分。(参考链接:讨论区链接

参考代码:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if(nums.empty()) return 0;
        int n=nums.size();
        vector<int> dp(n+1,0);
        int len=1;
        dp[len]=nums[0];
        for(int i=1;i<nums.size();i++){
            if(nums[i]>dp[len]) dp[++len]=nums[i];
            else{
                int l=1,r=len,pos=0;// 如果找不到说明所有的数都比 nums[i] 大,此时要更新 d[1],所以这里将 pos 设为 0
                while(l<=r){
                    int mid=l+(r-l)/2;
                    if(dp[mid]<nums[i]) {
                        pos=mid;
                        l=mid+1;
                    }
                    else r=mid-1;
                }
                dp[pos+1]=nums[i];
            }
        }
        return len;
    }
};





以上是关于leetcode300 最长上升子序列(Medium)的主要内容,如果未能解决你的问题,请参考以下文章

leetcode300 最长上升子序列(Medium)

Leetcode-300. 最长上升子序列

Leetcode 300.最长上升子序列

leetcode-300最长上升子序列

leetcode300.最长上升子序列

leetcode 300. 最长上升子序列