思路与算法
- 假设对于以 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
N 是
nums
的长度。有两个 for 循环是 O ( 1 ) O(1) O(1)。 - 空间复杂度:
O
(
N
)
O(N)
O(N),
dp
和counts
所用的空间。