動態規划思想
注意:子串和子序列的區別
子串一定時連續的,子序列不一定是連續的

首先清楚dp數組的含義
定義:dp[i]表示以nums[i]這個數結尾的最長遞增子序列的長度

因為nums[3]=4,最長遞增子序列為1,3,4,所以長度為3即dp[3]=3
既然是遞增子序列,只要找到前面那些結尾比4小的子序列,然后把4接到最后,就可以形成一個新的遞增子序列,長度加1
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
# 初始化dp數組為1
dp = [1] * len(nums)
for i in range(len(nums)):
for j in range(i):
if nums[i] > nums[j]:
dp[i] = max(dp[i], dp[j]+1)
res = 0
for i in range(len(dp)):
res = max(res, dp[i])
return res

class Solution:
def findNumberOfLIS(self, nums: List[int]) -> int:
if not nums:
return 0
# length表示以x為結尾的最長遞增子序列的長度
length = [1 for _ in range(len(nums))]
# count 表示以x為結尾的最長遞增子序列的個數
count = [1 for _ in range(len(nums))]
for i in range(len(nums)):
for j in range(i):
if nums[i] > nums[j]:
# 在初始化的length表基礎上,正常都是length前面的值小於等於length后面的值(初始化為1)
if length[j] >= length[i]:
length[i] = length[j] + 1
count[i] = count[j]
# 如果遇到這個i前面兩個相同的值,第二次進入這個條件時,這個i已經是做過length[i] = length[j] + 1,即有兩個長度相同的子序列
elif length[j] + 1 == length[i]:
count[i] += count[j]
res = 0
# 找最長遞增子序列,要在length中找長度最長的子序列個數之和
maxSub = max(length)
for i in range(len(nums)):
if length[i] == maxSub:
res += count[i]
return res
