0
点赞
收藏
分享

微信扫一扫

【LeetCode】673.最长递增子序列的个数(可不连续)& 674. 最长递增子序列的长度 (动态规划)


一、最长递增子序列的个数

"""             【动态规划】
673
给定一个未排序的整数数组,找到最长递增子序列的个数 (可不连续)。
输入: [1,3,5,4,7]
输出: 2
解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。
"""

"""
【复杂度分析】

时间复杂度:O(N^2),其中 N 是 nums 的长度。
空间复杂度:O(N),lengths 和 counts 所用的空间。
"""

from typing import List
class Solution:
def findNumberOfLIS(self, nums: List[int]) -> int:
L = len(nums)
if L <=1:
return L
maxLen = [1] * L
count = [1] *L

for i in range(1, L):
for j in range(0,i):
if nums[j] < nums[i]:
if maxLen[j]+1 > maxLen[i]: # 等效成 maxLen[i] = max(maxLen[i], maxLen[j] + 1) 但是这样就不方便加其他语句
maxLen[i] = maxLen[j]+1
count[i] = count[j]
elif maxLen[j]+1 == maxLen[i]:
count[i] = count[i] + count[j]

print("maxLen:",maxLen)
print("count:", count)
ans = 0
max_maxLen = max(maxLen) # !!! 先计算出来,防止在下面的for循环中反复计算,节省时间 !!!
for k in range(L):
if maxLen[k] == max_maxLen:
ans = ans + count[k] # 有可能有重复的数,如 [1,3,5,4,7,7]

return ans

if __name__ == '__main__':

nums = [1,3,5,4,7,7]
solution = Solution()
ans = solution.findNumberOfLIS(nums)
print("ans:",ans)

二、最长递增子序列的长度

"""             【动态规划】 "人人为我"递推型  时间复杂度 O(n^2)
674
给定一个未排序的整数数组,找到最长递增子序列的长度 (可不连续)。
输入: [1,3,5,4,7]
输出: 4
解释: 最长(不连续)递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7] 长度均为 4。
"""

from typing import List
class Solution:
def findNumberOfLIS(self, nums: List[int]) -> int:

L = len(nums)
if L <=1:
return L

maxLen = [1] * L # 存放每一个 maxLen[i],最后一个 maxLen[-1]即所求答案

for i in range(1,L): # 每次求以第i个数 a(i)为 【终点】的最长上升子序列长度
for j in range(0,i): # 查看第i个数a(i)左边,以第 j 个数a(j)为终点的最长上升子序列
if (nums[j] < nums[i]): # 也就是在以 a[j]为终点的最长上升子序列的基础上加a[i],即长度加1,也就是以a[i]为终点的最长上升子序列
maxLen[i] = max(maxLen[i], maxLen[j] + 1) # maxLen[i] 至少可以是maxLen[j]+1,只有当maxLen[j]+1>maxLen[i],才更新maxLen[i]
# 所以上一句取max操作,等效成 if maxLen[j] + 1 > maxLen[i]: maxLen[i] = maxLen[j] + 1

# else: # 这个else部分不正确
# maxLen[i] = 1
print("maxLen:",maxLen)
return max(maxLen)

if __name__ == '__main__':

nums = [1,3,5,4,7]
#nums = [1, 5, 7, 9, 15, 10, 11,6, 2, 7]
#nums = [1]
solution = Solution()

L = solution.findNumberOfLIS(nums)

print(L)


举报

相关推荐

0 条评论