0673:最长递增子序列的个数(★)
目录
题目
给定一个未排序的整数数组 nums , 返回最长递增子序列的个数 。
注意 这个数列必须是 严格 递增的。
示例 1:
输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。
示例 2:
输入: [2,2,2,2,2] 输出: 5 解释: 最长递增子序列的长度是1,并且存在5个子序列的长度为1,因此输出5。
提示:
1 <= nums.length <= 2000-106 <= nums[i] <= 106
相似问题:
分析
#1
- 0300 的升级版,可以先求出 f[j] 代表结尾位置 j 的最长递增子序列长度。
- 再令 g[j] 代表结尾位置 j 的最长递增子序列长度的个数,则: g[j] = sum(g[i] for i in range(j) if nums[i]<nums[j] and f[i]=f[j]-1) or 1
- 最终所有满足 f[j]=max(f) 的 g[j] 之和即为所求。
|
|
895 ms
#2
- 0300 中能优化 f 的递推。考虑能否优化 g 的递推
- 注意到递推 g[j] 时,只需要满足 f[i]=f[j]-1 的位置 i
- 考虑维护 B 代表 f[i]=x 的所有 <nums[i],g[i]>,问题转为求 sum(b for a,b in B[f[j]-1] if a<nums[j]),然后将 <nums[j],g[j]> 添加到 B[f[j]] 中即可维护 B
- 找位置 i 类似 0300,二分即可
- 注意到 B 中的 nums[i] 必然是递减的,所以利用前缀和+二分即可快速计算 g[j]
解答
|
|
15 ms