LeetCode 673. 最长递增子序列的个数(Python、动态规划)

题目描述

思路与算法

  • 假设对于以 n u m s [ i ] nums[i] nums[i] 结尾的序列,我们知道最长序列的长度 d p [ i ] dp[i] dp[i],以及具有该长度序列的个数 c o u n t [ i ] count[i] count[i]
  • 对于每一个 j < i j < i j<i 和一个 n u m s [ j ] < n u m s [ i ] nums[j] < nums[i] nums[j]<nums[i]
    • 如果 d p [ j ] ≥ [ i ] dp[j] \geq [i] dp[j][i] ,那么我们就知道我们有 c o u n t [ j ] count[j] count[j] 个长度为 d p [ i ] dp[i] dp[i] 的序列。
    • 如果 d p [ i ] = = d p [ j ] + 1 dp[i] == dp[j] + 1 dp[i]==dp[j]+1,那么我们就知道现在有 c o u n t [ j ] count[j] count[j] 个额外的序列(即 c o u n t [ i ] + = c o u n t [ j ] count[i] += count[j] count[i]+=count[j])。
class Solution:
    def findNumberOfLIS(self, nums: List[int]) -> int:
        dp = [1 for i in range(len(nums))]  # dp[i]表示以nums[i]结尾的最长LIS的长度
        count = [1 for i in range(len(nums))]   # count[i]表示以nums[i]结尾的最长LIS个数
        for i in range(len(nums)):
            for j in range(i):
                if nums[j] < nums[i]:
                    if dp[j] >= dp[i]:
                        # 说明此时nums[i]直接附加在以nums[j]结尾的LIS后,以nums[i]结尾的LIS数量即为以nums[j]结尾的LIS数量
                        dp[i] += 1
                        count[i] = count[j]
                    elif dp[i] == dp[j] + 1:
                        # 说明此时又找到了另一条以nums[i]结尾的LIS路径,以nums[i]结尾的LIS数量即为当前数量加上以nums[j]结尾的LIS数量
                        count[i] += count[j]
        longestLIS = max(dp)
        result = sum([c for i, c in enumerate(count) if dp[i] == longestLIS])
        return result

在这里插入图片描述

复杂度分析

  • 时间复杂度: O ( N 2 ) O(N^2) O(N2)。其中 N N Nnums 的长度。有两个 for 循环是 O ( 1 ) O(1) O(1)
  • 空间复杂度: O ( N ) O(N) O(N)dpcounts 所用的空间。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值