🥈Medium

给你一个整数数组 nums,找到其中最长严格递增子序列的长度。

子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]是数组[0,3,1,6,2,2,7] 的子序列。

示例 1

  1. 输入:nums = [10,9,2,5,3,7,101,18]
  2. 输出:4
  3. 解释:最长递增子序列是 [2,3,7,101],因此长度为 4

示例 2

  1. 输入:nums = [0,1,0,3,2,3]
  2. 输出:4

示例 3

  1. 输入:nums = [7,7,7,7,7,7,7]
  2. 输出:1

提示

  • 1 <= nums.length <= 2500
  • 🥈300. 最长递增子序列@ - 图1<= nums[i] <= 🥈300. 最长递增子序列@ - 图2


    进阶

  • 你可以设计时间复杂度为 🥈300. 最长递增子序列@ - 图3的解决方案吗?

  • 你能将算法的时间复杂度降低到🥈300. 最长递增子序列@ - 图4吗?

题解

🙃想了很久还是没思路!!

动态规划

🥈300. 最长递增子序列@ - 图5为前🥈300. 最长递增子序列@ - 图6个元素中,最长上升子序列的长度。从头到尾计算🥈300. 最长递增子序列@ - 图7的值,很明显,要计算🥈300. 最长递增子序列@ - 图8时,已经计算出🥈300. 最长递增子序列@ - 图9的值。则状态转移方程就是:

🥈300. 最长递增子序列@ - 图10

即考虑往🥈300. 最长递增子序列@ - 图11中最长上升子序列后面再加一个🥈300. 最长递增子序列@ - 图12。因为🥈300. 最长递增子序列@ - 图13代表🥈300. 最长递增子序列@ - 图14中以🥈300. 最长递增子序列@ - 图15结尾的最长上升子序列,所以如果能从🥈300. 最长递增子序列@ - 图16状态转移过来,那么🥈300. 最长递增子序列@ - 图17必然大于🥈300. 最长递增子序列@ - 图18,这样才能将🥈300. 最长递增子序列@ - 图19放在🥈300. 最长递增子序列@ - 图20后面形成更长的上升子序列。

最后,整个数组最长上升子序列即所有🥈300. 最长递增子序列@ - 图21中的最大值:

🥈300. 最长递增子序列@ - 图22

Python

  1. class Solution:
  2. def lengthOfLIS(self, nums: List[int]) -> int:
  3. if not nums:
  4. return 0
  5. dp = []
  6. for i in range(len(nums)):
  7. dp.append(1)
  8. for j in range(i):
  9. if nums[i] > nums[j]:
  10. dp[i] = max(dp[i], dp[j] + 1)
  11. return max(dp)