【LeetCode刷题】300 最长上升子序列

本文深入探讨了求解最长上升子序列问题的动态规划方法,通过实例详细讲解了算法思路与实现过程,展示了如何利用动态规划降低重复计算量,提高效率。

300、最长上升子序列

题目描述:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4

思路:利用动态规划
用dp[i] 表示 从下标0 到下标i 的最长上升子序列的长度,例如对于样例输入[10,9,2,5,3,7,101,18], 有 dp = [ 1, 1, 1, 2, 2, 3, 4, 4]。显然dp[0] = 1,对于任意的i 不为零的情况,应该在 i 的左侧找一个下标 j ,其满足两个条件:

1.nums[ j ]比 nums[ i ] 小;
2.它是所有满足条件1里 dp [j] 最大的那个;

即:dp[i] = max(dp[j] + 1,dp[i]) , j < i and nums[ j ] < nums[ i ]

如果不存在这样的下标j,说明在0 ~ i - 1 的范围内,所有元素都比nums[i] 大,即无法找到一个能和 nums[i] 组成上升子序列的元素,所以dp[i] = 1, 表示为nums[i] 自身成为一个长度为1 的上升子序列。

class Solution(object):
    def lengthOfLIS(self, nums):
        if not nums:
            return 0
        a = [1 for i in range(len(nums))]  #单个元素的时候,最长序列为1
        for i in range(1,len(nums)):
            for j in range(0,i):
                if nums[i] > nums[j]:
                    a[i] = max(a[j] + 1, a[i])  # i前边有j个元素的时候,需要确保a[i]的值能取到最大

        return max(a)

nums = [10,9,2,2,3,3]
print(Solution().lengthOfLIS(nums))

总结:利用一个列表保存每一步的值,来降低重复计算量,这种动态规划方法经常用到,比如之前的爬楼梯或者跳台阶,都是同样的思想,当然我们也可以利用递归法来解决。

最后我们在列一下动态规划求解问题的四个特征:
①求一个问题的最优解;
②整体的问题的最优解是依赖于各个子问题的最优解;
③小问题之间还有相互重叠的更小的子问题;
④从上往下分析问题,从下往上求解问题;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jeremy-Sky

你的鼓励是我的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值