leetcode 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

在leetcode 1143 最长公共子序列中,dp[i][j]只是定义了在0-i,0-j这个范围内的最长公共子序列,不一定是一定要以i-1和j-1结尾。但是这里存在一个判断递增的问题,如果不以边界i结尾的话,如何判断呢?

定义dp[i]为以nums[i]结尾的最长递增子序列的长度(这个子序列一定是以nums[i]结尾),为了得到它的值,需要遍历j=[0,i-1], 将以 j 结尾的最长递增子序列 + nums[i]

  1. 如果nums[i] > nums[j] 则说明以 nums[j] 结尾的最长子序列如果加上 nums[i] 则仍然是递增序列,且长度又可以加1
  2. 否则不能形成递增序列
    求上诉所有能形成递增序列的序列的最大长度,就是dp[i]

边界条件: 以任意一个i 位置结尾的递增子序列的极小值是1,因为一个字符本身形成一个递增子序列。因此dp所有位置初始为1

最终结果是遍历dp,求最大值,即遍历以各个位置为结尾的最长递增子序列,取他们的里面最大的那一个.
时间复杂度O(n2)

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        dp = [1]*len(nums)
        gm = 1
        for i in range(1, len(nums)):
            for j in range(i):
                if nums[i] > nums[j]:
                    dp[i] = max(dp[j] + 1, dp[i])
            gm = max(dp[i], gm)
        return gm 

采用贪心+二分查找,时间复杂度能降低到O(nlogn)

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        dn = [nums[0]]
        n = len(nums)
        for i in range(1, n):
            if nums[i] > dn[-1]:
                dn.append(nums[i])
            else:
                loc = self.bisect_search(dn, nums[i])
                dn[loc] = nums[i]
        return len(dn)



    def bisect_search(self, dn, target):
        l, r = 0, len(dn)-1
        while l <= r:
            mid = (l+r) // 2 
            if dn[mid] >= target:
                loc = mid 
                r = mid - 1 
            else:
                l = mid + 1
        return loc 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值