Leetcode 300. 最长上升子序列(n方dp,nlogn贪心+二分查找)

时间:2022-07-26
本文章向大家介绍Leetcode 300. 最长上升子序列(n方dp,nlogn贪心+二分查找),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

300. 最长上升子序列

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

示例:

输入: [10,9,2,5,3,7,101,18]
输出: 4 

解释: 最长的上升子序列是 [2,3,7,101],
它的长度是 
4

说明:

  • 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
  • 你算法的时间复杂度应该为 O(n2) 。

进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

n方做法:

dp[i]=max(dp[j]+1,dp[i]),

,

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
//定义 dp[i]dp[i] 为考虑前 ii 个元素,以第 ii 个数字结尾的最长上升子序列的长度,注意 textit{nums}[i]nums[i] 必须被选取。

    int dp[nums.size()+5];
    for(int i=0;i<nums.size()+5;i++)dp[i]=1;
    int maxx=1;
    int k=nums.size();
    if(!k)return 0;
    for(int i=1;i<k;i++)
    {
        for(int j=i-1;j>=0;j--)
        if(nums[i]>nums[j])dp[i]=max(dp[j]+1,dp[i]),maxx=max(maxx,dp[i]);
    }
    return maxx;
    }
};

nlogn做法:

d[i]表示长度为i的末尾元素值,遍历一遍nums,遇到比当前d[len]元素大的就接在后面,否则就二分插入d[1~len]中的某个位置~

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int k=nums.size();
        if(!k)return 0;
        vector<int>d;
        d.push_back(nums[0]);//表示长度i末尾元素值
        int len=1;
        for(int i=1;i<nums.size();i++)
        {
            if(nums[i]>d[len-1])d.push_back(nums[i]),len++;
            else
            {
                *lower_bound(d.begin(),d.end(),nums[i])=nums[i];
            }
        }
        return len;
    }
};