Leetcode-最长递增子序列

最长递增子序列
在这里插入图片描述

回溯

回溯三问:

ItemsDescription
当前操作j∈[0, (n-1)]枚举 nums [j]
子问题数组前 i 个元素中最大的 LIS 长度
以 nums[i] 结尾的 LIS最大长度
子子问题以 nums[j] 结尾的最大 LIS 长度

边界条件:i == 0时,返回1

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        n = len(nums)
        @cache
        def dfs(i):
            if i==0:
                return 1
            ans = 1
            for x in range (i):
                if nums[x] < nums[i]:
                    ans = max(dfs(x)+1,ans)
            return ans
        ans = 1
        for i in range(n):
            ans = max(dfs(i),ans)
        return ans

时间复杂度为O(n^2).使用记忆化搜索后,每个dfs(x)的计算时间为O(x).

递推

  1. f[i] 末尾为nums[i]的最大LIS长度
  2. 递推公式:f[i] = max(f[j])+1 # j<i
  3. 初始化: f = [1]*n,
  4. 便利顺序: 需要更新后的左边f[j],顺序便利
class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        n = len(nums)
        f = [0]*n
        for i in range(n):
            ans = 1
            for j in range(i):
                if nums[j] < nums[i]:
                    ans = max(f[j]+1,ans)
            f[i] = ans
        return max(f)

时间复杂度为O(n^2).

二分&贪心

我们将问题反转:找到长度为某定值下,末尾元素中的最小值。最小的末尾元素,才能找到最长LIS。
Ex:nums = [1,6,8,2,5,6,3]
g[x]表示长度为x+1LIS,末尾元素的最小值

当前便利值更新情况
1g[0] = 1; g = [1]
6g[1] = 6; g = [1,6]
8g[2] = 8; g = [1,6,8]
2g[1] = 2; g = [1,2,8]
5g[2] = 5; g = [1,2,5]
6g[3] = 6; g = [1,2,5,6]
3g[2] = 3; g = [1,2,3,6]

最终可以看到,g 的长度就是结果。

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        g = []
        for x in nums:
            j = bisect_left(g,x)
            if j==len(g):
                g.append(x)
            else :
                g[j] =x
        return len(g)

时间复杂度O(nlogn)
bisect_left(a, x, lo=0, hi=len(a))
返回 x 在有序列表 a 中的最左插入位置,使得插入后列表仍然有序。
如果 x 已经存在于 a 中,返回第一个等于 x 的索引。
如果 x 不存在,返回第一个大于 x 的元素的索引(即 x 应该插入的位置)。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值