最长递增子序列
本篇基于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 = 0for j in range(i):if nums[j] < nums[i]:res = max(dp[j], res)res += 1dp[i] = res # 将返回值存到dp数组return max(dp)
由于将原数组排序和去重后,数组内的任意一个子序列都是递增的,求原数组的最长严格递增子序列就等于求 原数组 与 排序去重后的数组的最长公共子序列。