1. 程式人生 > 其它 >序列型動態規劃——最長遞增子序列

序列型動態規劃——最長遞增子序列

技術標籤:動態規劃力扣每日一題演算法動態規劃leetcode

給你一個整數陣列 nums ,找到其中最長嚴格遞增子序列的長度。

子序列是由陣列派生而來的序列,刪除(或不刪除)陣列中的元素而不改變其餘元素的順序。例如,[3,6,2,7] 是陣列 [0,3,1,6,2,2,7] 的子序列。

示例 :

輸入:nums = [10,9,2,5,3,7,101,18]
輸出:4
解釋:最長遞增子序列是 [2,3,7,101],因此長度為 4 。

1、題目分析

這是典型的序列型別動態規劃題目。

2、確定狀態

最後一份:對於最優的策略,一定有最後一個元素a[j]。

第一種情況:最優策略中最長上升子序列為{a[j]},答案就是1

第二種情況子序列長度大於1,那麼最優策略中a[j]前一個元素是a[i],並且a[i]<a[j]。

因為是最優策略,那麼它選中的以a[j]結尾的上升子序列一定是最長的。

但是因為不確定a[j]前一個元素是誰,因此需要列舉每個i,轉化為子問題:i<j。

綜上所述,我們可以假設狀態:f[i]表示以a[i]結尾的最長上升子序列的長度。

3、轉移方程

f[i]表示以a[i]結尾的最長上升子序列的長度。

在這裡插入圖片描述

4、初始條件和邊界情況

情況2必須滿足i>0,a[j]>a[i],滿足單調性

初始條件:空

5、計算順序

從小大到計算。

答案是max{f[0],f[1],f[2]……,f[n-1]}

演算法時間複雜度O(n*n),空間複雜度O(n)

6、程式碼實現

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if len(nums)==0:
            return 0
        dp = [0 for i in range(len(nums))]
        dp[0]=1
        max1 = 1
        for i in range(1,len(nums)):