点击上方蓝字设为星标
每周一、三、五上午 8:30 准时推送
下面开始今天的学习~![8763bf52df48a87de52e4181b753d37d.png](https://i-blog.csdnimg.cn/blog_migrate/f4648c21d2ba19f2afc6117eb61cd15b.png)
力扣题解
自题解功能上线以来
题解区涌现了很多优质题解
如果你有更好的解题思路
不如来题解区大显身手
你可获得
1.力扣官方平台推荐
2.力扣积分
1篇精选题解:200 力扣积分
(注:题解著作版权归发布者本人所有)
本期精选题解由我们的用户“ColdMe”倾情撰写,一起来看看吧!
300. 最长上升子序列(点击文末阅读原文查看题目)
题目描述
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
- 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n^2) 。
解决方案
动态规划
子序列的问题->动态规划。- 使用数组
cell
保存每步子问题的最优解。 cell[i]
代表含第i
个元素的最长上升子序列的长度。- 求解
cell[i]
时,向前遍历找出比i
元素小的元素j
,令cell[i]
为max(cell[i],cell[j]+1)
。
class Solution: def lengthOfLIS(self, nums: List[int]) -> int: if nums == []: return 0 cell = [1] for i in range(1,len(nums)): cell.append(1) for j in range(i): if(nums[j] < nums[i]): cell[i] = max(cell[i], cell[j]+1) return max(cell)
复杂度分析
时间复杂度
:O(n^2),双层遍历
空间复杂度
:O(n)
动态规划 + 二分查找
很具小巧思。新建数组cell
,用于保存最长上升子序列。
对原序列进行遍历,将每位元素二分插入 cell
中。
- 如果
cell
中元素都比它小,将它插到最后 - 否则,用它覆盖掉比它大的元素中最小的那个。
cell
中存储比较小的元素。这样,
cell
未必是真实的最长上升子序列,但长度是对的。
Python 实现
class Solution: def lengthOfLIS(self, nums: List[int]) -> int: size = len(nums) if size<2: return size cell = [nums[0]] for num in nums[1:]: if num>cell[-1]: cell.append(num) continue l,r = 0,len(cell)-1 while l mid = l + (r - l) // 2 if cell[mid] l = mid + 1 else: r = mid cell[l] = num return len(cell)
本文作者:ColdMe
编辑&版式:霍霍
声明:本文归作者版权所有,如需转载请联系。
点个在看,少个 bug?