673.最长递增子序列的个数
给定一个未排序的整数数组,找到最长递增子序列的个数。
题目链接:673. 最长递增子序列的个数 - 力扣(LeetCode) (leetcode-cn.com)
动态规划
思路
这题对于dp数组的处理与leetcode300题相同。
-
首先确定动态数组
dp[i]的含义:表示到数组第i位置为止最长递增子序列的长度 -
确定动态转移方程:
- 遍历已知数组从位置
0到位置i-1,若nums[i] > nums[j]说明当前i位置的数可以和0~j已经组成递增子序列的序列组成更长的子序列。 dp[i] = max( dp[i] , dp[j]+1 )
- 遍历已知数组从位置
-
但是此题最后问的是最长递增子序列的个数,于是我们增加一个
count数组,count[i]表示以nums[i]为末尾的最长子序列的个数。怎么更新count数组呢?- 当
dp[i] < dp[j]+1时说明以此数字结尾的最长子序列长度更新了,那么这样长度的个数就是以nums[j]为结尾的最长子序列的个数。即count[i] = count[j] - 当
dp[i] == dp[j]+1时说明最长长度没有更新但是个数增加了,要加上以nums[j]为结尾的最长子序列的个数,即count[i] += count[j]
- 当
-
在更新
dp数组的同时可以顺便找到最大子序列长度max_length -
最后遍历
dp,找到所有与max_length相等的dp[i],将他们的count的累加,即res += count[i]
class Solution:
def findNumberOfLIS(self, nums: List[int]) -> int:
n = len(nums)
if n == 1:
return 1
dp = [1] * n
count = [1] * n
max_length = 0
for i in range(1,n):
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[i] == dp[j]+1:
count[i] += count[j]
max_length =max(max_length,dp[i])
res = 0
for i in range(n):
if dp[i] == max_length:
res += count[i]
return res
浙公网安备 33010602011771号