leetcode300. 最长递增子序列

动态规划解法最重要的两点:

  1. 明确dp数组的定义
  2. 根据定义找到状态转移方程
    针对本题,我们定义dp数组是以数字num[i]结尾的最长递增子序列
    这样容易推导出状态转移方程dp[i]应该是j < i 且 num[j] < num[i]里的最长子序列再加上num[i]这个数组成的新数列
def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        dp = [1]*n 
        for i in range(n):
            for j in range(i):
                if nums[j] < nums[i]:
                    dp[i] = max(dp[i],dp[j] + 1)
        res = 0
        for i in range(n):
            res = max(res,dp[i])
        return res

二分法计算:具体思路参考耐心排序
做法是把这些数字分堆,规则是把点数小的值放到点数比它大的值上作为一堆;如果当前值较大没有可以放置的堆,则新建一个堆,把这个大值放进去;如果当前值有多个堆可供选择,则选择最左边的那一堆放置。堆的数量就是最长递增子序列的长度
下面算法进行了简化,小的值直接覆盖在比它大的最左边的堆上,所以只用一个栈就可以完成了

def lengthOfLIS(self, nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    stack = [-10005]
    n = len(nums)
    for i in range(n):
        if nums[i] > stack[-1]:
            stack.append(nums[i])
        else:
            index = bisect.bisect_left(stack,nums[i])
            stack[index] = nums[i]
    return len(stack) - 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值