最長上升子序列的長度&最長上升子序列的個數(動態規划)


動態規划思想

注意:子串和子序列的區別

子串一定時連續的,子序列不一定是連續的

首先清楚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

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM