要用到两个动态规划数组,时间复杂度O(n^2),空间复杂度O(n)。
class Solution:
def findNumberOfLIS(self, nums: List[int]) -> int:
'''
state: dp[i]表示以nums[i]结尾的最长递增子序列的长度
count[i]表示以nums[i]结尾的最长递增子序列的数量
basecase: 每遍历一个nums[i],dp[i]和count[i]均为1
transfer: 每遍历到一个nums[i],要从头遍历nums[j],
若nums[i]>nums[j],则分情况更新dp[i]和count[i]
result: res
'''
n = len(nums)
maxLen = res = 0 # maxLen表示全局上最长的递增子序列的长度
dp = [0] * n
count = [0] * n
for i in range(n):
dp[i] = count[i] = 1
for j in range(i):
if nums[i] > nums[j]:
# 找到了更长的递增子序列长度
if dp[j] + 1 > dp[i]:
dp[i] = dp[j] + 1
count[i] = count[j]
# 找到了当前递增子序列长度的不同构成路径
elif dp[j] + 1 == dp[i]:
count[i] += count[j]
# 当前的递增子序列长度超过了旧最大长度,更新结果
if dp[i] > maxLen:
maxLen = dp[i]
res = count[i]
# 当前的递增子序列长度与旧最大长度相同,即找到了不同构造路径的最长递增子序列
elif dp[i] == maxLen:
res += count[i]
return res