递增子序列的相关题目总结

最长递增子序列的nlog(n)算法 最长递增子序列 问题定义 解决思路 测试题目 问题定义 输入 一个非空整数数组AA,数组大小为NN。 输出 数组 AA中最长递增(严格递增)子序长度。其中,子序可以是不连续的。 解决思路 动态规划 动态规划的方法可以参考 《编程之美》里面第二章16题。 核心思路:每增加一个新元素时,寻找比其小的所有元素,并找出以这些元素为结束的递增子序里长度最大的加一(此结果是以新元素结尾的最长递增子序的长 阅读详情

目录

1. 最长连续递增序列

2. 最长上升子序列

3、最长递增子序列的个数

4、递增子序列

5、最长连续序列


这里总结一些递增子序列的相关题目,有的题目中会有最优解,但是这里主要关注的是动态规划的做法,所以只写出动态规划或者通用的一些方法。

介绍这些题目之前,先分清一下什么是子序列,什么是子串

子序列:子序列是不连续的,如序列 [4, 6, 5] 是 [1, 2, 4, 3, 7, 6, 5] 的一个子序列

子串:子串是连续的

1. 最长连续递增序列

输入: [1,3,5,4,7]
输出: 3
解释: 最长连续递增序列是 [1,3,5], 长度为3。
尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为5和7在原数组里被4隔开。 

这道题说的是递增序列,但是要求是连续的,所以其实是求递增子串

class Solution:
    def findLengthOfLCIS(self, nums: List[int]) -> int:
        if not nums:
            return 0
        if len(nums) == 1:
            return 1
        dp = [1]*len(nums) #代表连续递增序列的长度
        for i in range(1,len(nums)):
            if nums[i]>nums[i-1]: #如果后一个元素大于前一个元素,那长度+1
                dp[i] = dp[i-1]+1
        return max(dp) # 找出最大的那个数就是长度,不能是dp[-1],dp[-1]代表的是以最后一个元素结尾是最长连续递增序列,但是最后一个并不一定是最大的数。

2. 最长上升子序列

使用动态规划来做,定义dp数组表示子序列的长度,dp[i] 表示在第i 个元素之前的任意一个元素为起点,到第i个元素结尾的上升子序列的长度,初始化都为1,表示每个元素都至少可以单独成为子序列,此时长度都为 1。

遍历到每个元素 nums[i] 后,再从头遍历一下[0-i] 里的这些元素nums[j],如果nums[i]>nums[j],那nums[i]这个元素就可以接到nums[j] 这个元素的后面,即 dp[i] = dp[j] + 1 

所以递归方程就是  dp[i] = max(dp[i],dp[j]+1) 0\leq j<i,最后依旧是找max(dp),而不是dp[-1]

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if not nums:
            return 0
        dp=[1]*len(nums)
        for i in range(len(nums)):
            for j in range(i):
                if nums[i]>nums[j]:
                    dp[i] = max(dp[i],dp[j]+1)
        return max(dp)

这道题的内层循环如果每次都从0开始遍历,其实有很多重复的遍历,所以内层循环可以使用二分法来查找,找到第一个比num[i]大的数,然后替换成num[i],具体的不多说,代码如下:

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        res = []
        for num in nums:
            if not res or num>res[-1]:
                res.append(num)
            else:
                l=0
                r=len(res)-1
                while l<r:
                    mid = (l+r)//2
                    if res[mid]<num:
                        l = mid+1
                    else:
                        r = mid
                res[l]=num
        return len(res)

3、最长递增子序列的个数

这道题和上面那道题很像,只不过多了一个统计最长递增子序列的个数

class Solution:
    def findNumberOfLIS(self, nums: List[int]) -> int:
        if not nums:
            return 0
        dp = [1]*len(nums)
        count = [1]*len(nums)
        temp = 1
        res = 0
        for i in range(1,len(nums)):
            for j in range(i):
                if nums[i]>nums[j]:
                    if dp[j]+1>dp[i]:
                        dp[i] = dp[j]+1
                        count[i] = count[j]
                    elif dp[i] == dp[j]+1:
                        count[i]+=count[j]
            # temp = max(temp,dp[i])
        temp = max(dp)
        for i in range(len(nums)):
            if dp[i] == temp:
                res += count[i]
        return res

当 dp[j]+1 > dp [i] 时,说明第一次找到了新的长度,为dp[j]+1,这个时候count[i] = count[j],表明以 nums[i] 结尾的最长递增子序列的组合方式就等于 nums[j] 目前的组合方式

当 dp[j]+1 = dp [i] 时,说明这个长度的递增序列已找到过一次了,则 count[i]+=count[j],现有的组合方式个数加上 count [j] 的组合方式,即为总的组合方式个数

最后一次遍历是找到最长的那个长度,它所对应的count就是结果

这道题还可以用树状数组,目前能力有限,还不会树状数组,跳过

4、递增子序列

这道题不再是使用动态规划,而是深度优先搜索,类似于回溯,如果使用一般的回溯解法,耗时过慢,代码如下

class Solution:
    def __init__(self):
        self.res = []
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        
        def dfs(temp,start,nums):
            if len(temp)>=2 and temp not in self.res:
                self.res.append(temp[:])
            for i in range(start,len(nums)):
                if not temp or nums[i]>=temp[-1]:
                    temp.append(nums[i])
                    dfs(temp,i+1,nums)
                    temp.pop()
        temp = []
        dfs(temp,0,nums)
        return self.res

可以看到耗时六千多毫秒,使用集合来进行剪枝依旧耗时过长,可以使用字典来剪枝。

class Solution:
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        res = []
        def dfs(start, tmp):
            dic = {}
            if len(tmp) > 1:
                res.append(tmp)
            for i in range(start, len(nums)):
                if dic.get(nums[i], 0):
                    continue

                if len(tmp) == 0 or nums[i] >= tmp[-1]:
                    dic[nums[i]] = 1
                    dfs(i + 1, tmp + [nums[i]])


        dfs(0, [])
        return res

耗时一下子就降下来了。

5、最长连续序列

先空着,学习了并查集再来完善

Jetson Orin Nano GPIO 实战,用 devmem 玩转 Pinmux 引脚复用配置 devmem 是一个直接读写寄存器的工具,通过 mmap 将 /dev/mem 中的物理地址区域映射到用户空间进程地址空间,从而实现直接读写,正常情况下在 /dev 下可以看到 mem。可以看到对应 bit5 bit6 分别为 1,对应配置为 E_IO_HV 为 ENABLE 以及 E_INPUT 为 ENABLE。需要 TRM 手册查看相关寄存器,以及安装 busybox,busybox 内置了 devmem。根据 TRM 手册,找到 I2C_SDA 的 pinmux 地址偏移是 0x18。 阅读详情

相关推荐

用MATLAB从零实现六足机器人步态仿真:交替三角与波动步态保姆级教程

本文详细介绍了如何使用MATLAB从零实现六足机器人的两种经典步态仿真:交替三角支撑步态和波动步态。通过参数定义、相位设置、运动轨迹生成和三维可视化等步骤,帮助读者掌握六足机器人步态规划的核心技术。教程包含完整代码和详细解析,适合机器人爱好者和相关专业学生学习实践。

weixin_26765363的博客 226

“子序列问题”系列总结,一文读懂(Java实现)

该如何使用动态规划去解决有关“子序列”这一系列问题?

CYK_byte的博客 3410

Windows下Codex CLI binary报错排查与修复完整指南

在Windows开发环境中,命令行工具与图形界面应用的协同工作常常依赖于系统环境变量的正确配置。Codex CLI作为一款基于Node.js的智能编程命令行工具,其可执行文件(binary)的定位机制直接关系到桌面应用的正常启动。当用户执行npm更新或切换Node版本后,Codex CLI二进制文件路径可能发生漂移,从而触发“Unable to locate the Codex CLI binary”的报错。此类问题并非代码或账号异常,而是PATH路径、环境变量刷新及桌面应用缓存共同作用的结果。本文面向Wi

weixin_28718769的博客 304

leetcode-491. 递增子序列

leetcode - 491

sinat_41679123的博客 328

TensorFlow GPU版本安装步骤-Windows系统

本文由在Windows下安装TensorFlow GPU版本教程-优快云等整理得到。 目录 1、确认显卡是否支持CUDA 1.1 查看显卡信息 打开“设备管理器”,查看显卡信息,如下图所示: 由上图知,本电脑的显卡为NVIDIA Quadro P400. 1.2 查看支持CUDA的显卡 网址:https://developer.nvidia.com/cuda-gpus 经查询可知,该显卡支持CUDA,如下图所示: 2、安装CUDA 2.1 下载CUDA 网址:https://developer.nvi

x_lingyun的专栏 765

Python爬虫(一)京东商品价格及详情页抓取

这是一个以http://item.jd.com/2957726.html为例的单网页抓取案例 import urllib.request; #载入urllib.request,用于获取页面html源代码 from pandas import Series; #载入series包 from pandas import DataFrame; #载入dataframe包 from bs4 impo

Data Proc 1万+

最长递增子序列问题(你真的会了吗)

1.对应牛客网链接2.题目描述: 3.解题思路下面以[5,7,1,9,4,6,2,8,3]为例:4.对应代码:1.对应牛客网链接:2.题目描述: 3.解题思路:4.对应代码:1.对应letecode链接:2.题目描述:3.解题思路4.对应代码:...

qq_56999918的博客 9635

uniapp - 超详细的 H5 公众号网页微信登录示例代码,提供从 0-1 公众号配置及详细注释代码(站在新手小白的角度)第三方微信授权登录的实现!!

uniapp微信浏览器H5授权微信登录,UniApp开发H5接入微信登录的全过程,uniapp的H5页面使用微信登录,uniapp H5微信授权登录,H5之微信授权登陆 (uniapp网页版微信授权登录),uni-app开发H5第三方微信授权登录的实现,uniapp如何实现微信授权登录,公众号H5页面接入微信登录流程,uni-app - 最详细 H5 网页接入微信登录功能,提供公众号配置与详细注释示例代码(移动端网页实现点击登录按钮后 调用微信公众号授权登录功能 详细讲解接入流程与详细示例代码)官方最新超级

✅ 精选推荐文章 1万+

DAY52:动态规划(十七)子序列问题:最长递增子序列+最长连续递增序列+最长重复子数组

本题的最大值并不在dp数组末尾,因为每个数据都可能比前面的数字要小。最大长度可能是dp数组中间位置的dp[i],所以需要建个result存最大值。初始化要注意,本题每个以i为结尾的递增子序列,长度最小是1而不是0!本题难点在于,比较两个数组,得到重复且连续的最长子数组,用一维的DP数组无法同时表示两个数组的状态。我们需要用一个二维的矩阵来比较两个数组的所有状态。dp[0][j]和dp[i][0]的情况都需要单独初始化。

CFY1226的博客 1159

ubuntu下编译qtwebengine

ubuntu qtwebengine

tianyu的专栏 - Linux site:blog.youkuaiyun.com/wishfly 1463

OpenClaw用户必看:每天0成本使用OpenClaw!NVIDIA NIM免费大模型接入教程

🚀 OpenClaw接入NVIDIA NIM免费API!glm5、minimax-m2.5等大量模型任选,0成本升级AI助手!💰

XiaoqiangClub的博客 5577

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

算法题:最长递增子序列

的进阶版,用一个数组维护增长序列,那么这个增长序列数组就是有序的,就可以利用二分查找算法提升性能,另外题目的结果就是增长序列的长度,算法步骤:在遍历原数组的过程中,如果当前元素比增长序列数组的最后一个元素大就将当前元素加入增长序列数组,否责就在增长序列数组中就行二分查找,找到合适的位置,更新位置值为当前元素,这样做的目的是为了保证长度一样的情况下,保证递增序列的值最小,方便后续元素加入递增序列数组。---hard题解题思路。是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。

m0_61358347的博客 346

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

2025-3-1-4.10 动态规划(最长递增子序列(LIS)问题)

最长递增子序列 LIS

weixin_42269028的博客 519

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【贪心算法第六弹——334.递增的三元子序列(easy)】

【代码】【贪心算法第六弹——334.递增的三元子序列(easy)】

2301_80689220的博客 1180

LeetCode_491 递增子序列 /大厂笔试题讲解

目录标题一、题目信息二、解题思路三、解题代码四、其他好题分享 一、题目信息 本题和LeetCode_491相同,这里我以牛客网的形式写题。 二、解题思路 题目要求的只需要找到长度为三的子序列,还不要求是连续的。创建两个引用,first,second,分别表示第一大和第二大的数字,如果遍历的时候数组中还有比他们两个数还大的数字,那长度为3的子序列不就有了吗?如果遍历完了还么有,就说明是真的没有了,返回false。 还有其他两种情况 1、遍历数组的时候遇到的数(这里称为P)first比p大,既然连子序列.

guankunkunwd的博客 1471

子序列相关题目总结

特点:递增+不连续的子序列思路:每个节点的dp[i]取决于该节点前边所有节点的状态,前边比它小的节点的最大dp[i] 再加 1(故使用两层循环)

m0_72833525的博客 354

线性DP学习笔记(二):最长递增子序列, 将三个组排序

ps:笔记和代码按本人理解整理,重思路

学习记录 858

day 25 (代码随想录补卡)491.递增子序列|46.全排列 |47.全排列 II

【代码】day 25 (代码随想录补卡)491.递增子序列|46.全排列 |47.全排列 II。

qq_38788700的博客 358

(左程云)算法讲解072【必备】最长递增子序列问题与扩展

本节课讲述的是最优解,时间复杂度是O(n*logn),空间复杂度O(n),好实现、理解难度不大这个问题也可以用线段树来求解,时间和空间复杂度和本节讲的最优解没有区别,但需要理解线段树。

哀莫大于心死 724

算法套路十六——DP求解最长递增子序列LIS

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

Pistachiout的学习博客 1797

动规:子序列系列

本文介绍了常见的子序列动态规划问题及解法。主要内容包括:1. 最长递增子序列(LIS)的基本解法及变型;2. 摆动序列的双状态DP解法;3. 统计最长递增子序列个数的计数方法;4. 数对链问题转化为LIS的解法;5. 等差子序列的哈希表优化;6. 斐波那契子序列和等差子序列的二维DP解法。文章通过多个实例展示了如何利用动态规划解决各种子序列问题,并提供了详细的代码实现和优化思路。

_dindong的博客 1477

动态规划子序列问题系列一>最长递增子序列

【代码】动态规划子序列问题系列一>最长递增子序列。

robin_suli的博客 527

代码随想录算法训练营第二十五天| leetcode491.递增子序列、leetcode46.全排列、leetcode47.全排列 II

思路:用之前的方法,结果翻车了,好好看视频学新技能吧。

angela3264的博客 1041

力扣300.最长递增子序列

【代码】300.最长递增子序列。

A687479A的博客 274

【LeetCode题目详解】第九章 动态规划part13 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组 (day52补)

本题最关键的是要想到dp[i]由哪些状态可以推出来,并取最大值,那么很自然就能想到递推公式:dp[i] = max(dp[i], dp[j] + 1);子序列问题是动态规划的一个重要系列,本题算是入门题目,好戏刚刚开始!本题也是动规里子序列问题的经典题目,但也可以用贪心来做,大家也会发现贪心好像更简单一点,而且空间复杂度仅是O(1)。在动规分析中,关键是要理解和动态规划:300.最长递增子序列的区别。要联动起来,才能理解递增子序列怎么求,递增连续子序列又要怎么求。

weixin_67972246的博客 525
上一篇: 面试算法和数据结构中那些和 “K” 相关的题目
下一篇: 那些和“公共“有关的算法题
烟雨人长安
博客等级 码龄10年 871粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值