本篇基于b站灵茶山艾府。
300. 最长递增子序列
给你一个整数数组 nums
,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]
是数组 [0,3,1,6,2,2,7]
的。
示例 1:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:
输入:nums = [0,1,0,3,2,3]
输出:4
示例 3:
输入:nums = [7,7,7,7,7,7,7]
输出:1
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
# 由于最长递增子序列是组合,所以我们可以有选或不选/枚举选哪个两种思路
# 1.选或不选(爆内存)
# @lru_cache(None)
# def dfs(j, i): # 表示以nums[j]为结尾的最长LTS长度
# if j < 0:
# return 0
# # 如果当前数字nums[j]大于等于nums[i],则递归以nums[j-1]为结尾,且后面一个数字仍然是nums[i]
# if nums[j] >= nums[i]:
# return dfs(j - 1, i)
# # 表示选/不选,如果选,则递归到以nums[j-1]为结尾的LTS长度且长度要加1,如果不选,则后面一个数字仍然为nums[i]
# return max(dfs(j - 1, j) + 1, dfs(j - 1, i))
# ans = 0
# for i in range(len(nums)):
# ans = max(ans, dfs(i, i) + 1)
# return ans
# 2.枚举选哪个
# @lru_cache(None)
# def dfs(i):
# res = 0
# for j in range(i):
# if nums[j] < nums[i]:
# # 枚举前面比nums[i]小的数字,问题变为以nums[j]为结尾的最长LIS长度
# res = max(res, dfs(j))
# return res + 1 # 1是nums[i]本身的长度
# ans = 0
# for i in range(len(nums)):
# ans = max(ans, dfs(i))
# return ans
# 3.改成递推
dp = [0] * len(nums)
for i in range(len(nums)):
res = 0
for j in range(i):
if nums[j] < nums[i]:
res = max(dp[j], res)
res += 1
dp[i] = res # 将返回值存到dp数组
return max(dp)
由于将原数组排序和去重后,数组内的任意一个子序列都是递增的,求原数组的最长严格递增子序列就等于求 原数组 与 排序去重后的数组的最长公共子序列。