300. 最长递增子序列
一、题目
给你一个整数数组 nums
,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]
是数组 [0,3,1,6,2,2,7]
的子序列。
二、思路
dp[i]: 所有长度为i+1的递增子序列中, 最小的那个序列尾数. 由定义知dp数组必然是一个递增数组 依次判断每个数num将其插入dp数组相应的位置: 1. num > dp[-1], ,执行插入尾部操作,表示num比所有已知递增序列的尾数都大, 将num添加入dp 数组尾部 2. num <= dp [-1],则执行替换操作,【1,2,4,5】 现在来了一个3,那么替换为【1,2,3,5】,而不是【1,3, 4,5】
三、代码
class Solution: def lengthOfLIS(self, nums): n = len(nums) if n <= 1: # 不要忘了空数组 return n stack = [nums[0]] # 初始时候,只有一个元素,那么它肯定是递增的,所以加入 for i in range(1,n): if nums[i] > stack[-1]: stack.append(nums[i]) else: # 不会动递增序列的个数,但是会调整递增序列的值,这儿也可以用二分查找 for j in range(len(stack)): # dp=【1,2,4】 ,nums[i]=3 if nums[i] > stack[j]: continue else: stack[j] = nums[i] # 将数组中的值替换 break return len(stack) # 返回递增序列的长度,就是最长递增子序列
四、分析
复杂度分析
-
时间复杂度:O(n2),其中 n 为数组 nums 的长度。动态规划的状态数为 n,计算状态 dp[i] 时,需要 O(n) 的时间遍历 dp[0…i−1] 的所有状态,所以总时间复杂度为 O(n2)。
-
空间复杂度:O(n),需要额外使用长度为 n 的 dp 数组。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了