序列型動態規劃——最長遞增子序列
阿新 • • 發佈:2021-02-04
技術標籤:動態規劃力扣每日一題演算法動態規劃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)):