leet code300 最大上升序列长度

题目

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

1.基础动态规划方法

1.定义cell保存每个位置的最大序列长度
2.在当前位置往前找小于当前位置数值的数,更新cell

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if nums == []:
            return 0
        cell = [1]
        for i in range(1,len(nums)):
            cell.append(1)
            for j in range(i):
                if(nums[j] < nums[i]):
                    cell[i] = max(cell[i], cell[j]+1)
        return max(cell)

流程见下图:
动态规划
这种方法需要重复遍历每个位置之前的数据。。时间复杂度O(n^2)

2.动态规划+二叉搜索

1.遍历到每个位置都保存当前的最长序列dp
2.遍历下一个位置的时候如果比dp[-1]的值大,直接append到dp中,否则二叉判断其dp中的位置,把dp中该位置的值换成当遍历的数
3.dp中的值可能不是真实的上升序列,但是长度是对的

a = [10,6,4,0,3,1,9,10]
class Solution:
    def lengthOfLIS(self, nums):
        if len(nums) < 2:
            return len(nums)
        dp = [nums[0]]
        for num in nums[1:]:
            if dp[-1] < num:
                dp.append(num)
                continue
            l,r = 0,len(dp)-1
            while l<r:
                mid = (l + r) // 2
                if dp[mid] < num:
                    l = mid + 1
                else:
                    r = mid
            dp[l] = num
        return len(dp)
s = Solution()
s.lengthOfLIS(a)

流程:
在这里插入图片描述
这种方法相当于不断的把较小的值往dp中去排,越小的值越可能组成递增序列,是一种比较巧的方法,时间复杂度O(nlog(n))。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值