Leetcode 300. 最长递增子序列

该博客介绍了如何解决LeetCode上的第300题,即寻找给定整数数组中的最长严格递增子序列。通过提供C++代码,博主分别展示了动态规划和贪心+二分查找两种方法来求解问题,帮助读者理解并实现最长递增子序列的查找算法。

题目描述
给你一个整数数组 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.com/problems/longest-increasing-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

C++

方法1:

class Solution {
    /*
    动态规划
    dp[i]存放以nums[i]结尾的最长严格上升子序列的长度
    时间复杂度:O(n)
    */
public:
    int lengthOfLIS(vector<int>& nums) {
    if(nums.size()==0)  return 0;
    vector<int> dp(nums.size(),1);
    int res=1;
    for(int i=1;i<nums.size();i++){
        for(int j=0;j<i;j++){
            if(nums[j]<nums[i]){
                dp[i]=max(dp[i],dp[j]+1);
            }
        }
        res=max(res,dp[i]);  //省了一次遍历专门求最大值
    }
    return res;
    }
};

方法2
贪心+二分查找

class Solution {
    /*
     贪心+二分查找
     如果我们要使上升子序列尽可能的长,则我们需要让序列上升得尽可能慢,因此我们希望每次在上升子序列最后加上的那个数尽可能的小。
     维护子序列d[],遍历数组,对于每次的num[i],利用二分查找在d[]中找第一个小于nums[i]的位置K,然后将nums[i]跟新到d[k+1]
    */
public:
    int lengthOfLIS(vector<int>& nums) {
    if(nums.size()==0)  return 0;
    vector<int> d(nums.size());
    int len=1;
    d[len]=nums[0];
    for(int i=1; i<nums.size();i++){
        if(d[len]<nums[i]){
            d[++len]=nums[i];
            continue;
        }
        int left=1;
        int right=len;
        int pos=0;
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[i]>d[mid]){
                left=mid+1;
                pos=mid;   //最小值的最右边界,找d中从后向前第一个大于它的元素
            }
            else{
                right=mid-1;
            }
        d[pos+1]=nums[i];
        }
    }
    return len;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值