首页 > 其他分享 >300.最长递增子序列

300.最长递增子序列

时间:2023-06-13 15:48:05浏览次数:35  
标签:nums 300 递增 min len int tail 序列 dp

问题描述

300.最长递增子序列 本题简写为LIS问题,与LCS问题(最长公共子序列)相对。

解题思路

动态规划

关键在于,dp[i]表示什么含义便于解这道题,子序列不一定连续,所以为了便于求解,dp[i]应该表示为以nums[i - 1]结尾的最长严格递增子序列的长度;

递推关系为:

if (nums[i - 1] > nums[j - 1]) // j < i,表示nums[i - 1]前的任意一个元素
    dp[i] = max(dp[j] + 1, dp[i])

贪心

动态规划的时间复杂度为$O(n^2)$,这里存在一个时间复杂度更低的贪心解法:

动态规划的时间$O(n^2)$的时间复杂度中,$O(n)$的时间复杂度在与遍历整个数组,这是无法避免的;剩下的$O(n)$的时间复杂度,实际上在找一个满足j < i以及nums[j] < nums[i]的并且使dp[j]最大的j

那么,可以转化为找dp[j]固定的情况下,最小的一个nums[j],这样必然能够优先满足,nums[i] > nums[j];因此我们构造一个贪心数组:min_lenmin_len[i] = x表示长度为i的上升子序列的最小结尾元素为x。考虑到min_len一定是个单调递增的数组(易证),那么我们可以基于这个单调递增的特性,利用二分查找,找到满足min_len[j] < nums[i]的最大的j,即利用$O(\log n)$找到最佳转移位置。

代码

动态规划

class Solution {
  public:
    int lengthOfLIS(vector<int> &nums) {
        vector<int> dp(nums.size() + 1, 1); // dp[0]不考虑,至少有一个元素,所以初始化为1
        // dp[1] = 1;
        // int index = 0;
        int m = 0;
        for (int i = 1; i <= nums.size(); i++) {
            for (int j = 1; j < i; j++) {
                if (nums[i - 1] > nums[j - 1])
                    dp[i] = max(dp[j] + 1, dp[i]);
            }
            if (dp[i] > m)
                m = dp[i];
        }
        return m;
    }
};

贪心+二分

class Solution {
public:
    int GetIdx(vector<int> &min_len_tail, int len, int target) {
        int left = 1, right = len;
        int mid = left + (right - left) / 2;
        while (left < right) {
            if (min_len_tail[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
            mid = left + (right - left) / 2;
        }
        return left;
    }
    int lengthOfLIS(vector<int>& nums) {
        // 贪心,要让序列上升得尽可能慢
        // 先找到第一个波谷
        int n = nums.size();
        vector<int> min_len_tail(n + 1, nums[0]); //min_len_tail[i]表示长度为i的上升子序列的末尾元素的最小值
        int len = 1;
        for (int i = 1; i < n; i++) {
            if (nums[i] > min_len_tail[len]) {
                min_len_tail[++len] = nums[i];
            } else {
                int idx = GetIdx(min_len_tail, len, nums[i]);
                min_len_tail[idx] = nums[i];
            }
        }
        return len;
    }
};

标签:nums,300,递增,min,len,int,tail,序列,dp
From: https://www.cnblogs.com/zwyyy456/p/17477721.html

相关文章

  • 序列化和反序列化_demo
    参考:一文搞懂序列化与反序列化-知乎(zhihu.com)一、jdk序列化和反序列化module结构: FactInfo.javapackagecom.hmb;importjava.io.Serial;importjava.io.Serializable;publicclassFactInfoimplementsSerializable{@Serialprivatestaticfinall......
  • python基础day23 os模块和序列化模块
    os模块(重要,多)os模块是与操作系统交互的一个接口('a/aa/aaa/aaaa/aaaaa')#递归创建文件夹os.removedirs('a/aa/aaa')#上推删除空文件夹os.mkdir('aaa')#当前文件所在位置创建一个新的文件夹或文件os.mkdir('a.txt')os.rmdir('aaa')#删除当前文件所在位置平级......
  • CF3000 乱做
    CF1832F进行一个平凡的转化,求人和电网的交的最大值。因为电网的长度都相等,所以事实上是要求人和电网的中点离得尽量进,也就是说将人按照中点排序,每个电网的作用范围是一段区间。设\(f_{i,j}\)是\(i\)个电网控制前\(j\)个人,发现\(f_{i,j}=\max\limits_{k=1}^jf_{i-1,k-1}......
  • Python利用jsonpickle库把对象序列化为json
    python中经常要保存一些数据,json是一种理想的存储格式,纯文本的,也方便阅读,但有时使用起来不太方便,比如下面的例子:a=jsonData['A']b=jsonData['B']只能按字典方式引用,还不支持自动完成,不如python对象使用方便.如果定义python类,使用方便,但是保存为文件时......
  • os模块、序列化模块、pickle和json的区别
    os模块#os模块是与操作系统交互的一个接口1.文件相关的os.makedirs('dirname1/dirname2')#可生成多层递归目录os.removedirs('dirname1')#若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推os.mkdir('dirname')#生成单级目录;相当于shell中mkd......
  • python 序列化模块
    一、jsonJson模块提供了四个功能:dumps、dump、loads、load1、前景什么叫序列化——将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。序列化的目的以某种存储形式使自定义对象持久化;将对象从一个地方传递到另一个地方。使程序更具维护性2、loads和dumps......
  • 代理IP出现错误代码300是什么意思
    HTTP代理是我们在使用网络时常用的工具之一,它可以帮助我们隐藏IP地址、加快请求响应速度等,但在使用HTTP代理时有时候会遇到各种错误码。其中,错误码300也是比较常见的一种。那么,这个错误码代表什么情况呢?本文将为您介绍相关内容。首先,HTTP错误码300属于重定向响应状态码。它......
  • django views 序列化
      RESTframework中的序列化类与Django的Form和ModelForm类非常相似。我们提供了一个Serializer类,它提供了一种强大的通用方法来控制响应的输出,以及一个ModelSerializer类,它为创建处理模型实例和查询集的序列化提供了有效的快捷方式。Serializers 序列化器允许把像查询......
  • Java反序列化之Commons-Collection篇04-CC4链
    <1>环境分析因为CommonsCollections4除4.0的其他版本去掉了InvokerTransformer不再继承Serializable,导致无法序列化。同时CommonsCollections4的版本TransformingComparator继承了Serializable接口,而CommonsCollections3里是没有的。这个就提供了一个攻击的路径jd......
  • 使用外置存储设备扩展exroot(MT1300)
    环境说明:GL-INETMT1300设备一台8GU盘一个,已经格式化文件系统为EXT41.安装相关工具opkgupdateopkginstallblock-mountkmod-fs-ext4e2fsprogsfdisk 2.修改fstab配置文件,更改现有文件系统的挂载点DEVICE="$(sed-n-e"/\s\/overlay\s.*$/s///p"/etc/mtab)"uci-q......