线性dp(动态规划)

本篇基于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)

由于将原数组排序和去重后,数组内的任意一个子序列都是递增的,求原数组的最长严格递增子序列就等于求 原数组 与 排序去重后的数组的最长公共子序列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

noruta

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值