leetcode 300 最長上公升子串行

2021-10-08 17:36:20 字數 2285 閱讀 8972

300. 最長上公升子串行

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。

示例:輸入: [10,9,2,5,3,7,101,18]

輸出: 4

解釋: 最長的上公升子串行是 [2,3,7,101],它的長度是 4。

說明:可能會有多種最長上公升子串行的組合,你只需要輸出對應的長度即可。

你演算法的時間複雜度應該為 o(n2) 。

高階: 你能將演算法的時間複雜度降低到

由於這裡不是乙個連續的遞增,所以開始我打算使用棧來做,就不對。借鑑了大佬的思路。

動態規劃方法:dp[i] 表示第i個數字(包含)截至的最長遞增串的長度。由於每個數字都需要和前面的所有數字進行比較,所以是由兩個for迴圈組成。

這裡主要是dp動態轉移方程:

nums[i]是需要和前面比它小的數字的dp值加一來確定的,但是前面的數字中,比nums[i]小的數字可能有多個,我們就需要找乙個dp值最大的加一。所以形成了下面的遞推公式:

)#從前面的dp鍾選乙個最大的

return

max(dp)

使用二分查詢的方法做這道題:

來自威威大佬的題解

# 特判

if size <2:

return size

# 為了防止後序邏輯發生陣列索引越界,先把第 1 個數放進去

tail =

[nums[0]

]for i in

range(1

, size)

:# 【邏輯 1】比 tail 陣列實際有效的末尾的那個元素還大

# 先嘗試是否可以接在末尾

if nums[i]

> tail[-1

]:)continue

# 使用二分查詢法,在有序陣列 tail 中

# 找到第 1 個大於等於 nums[i] 的元素,嘗試讓那個元素更小

left =

0 right =

len(tail)-1

while left < right:

# 選左中位數不是偶然,而是有原因的,原因請見 leetcode 第 35 題題解

# mid = left + (right - left) // 2

mid =

(left + right)

>>

1if tail[mid]

< nums[i]

:# 中位數肯定不是要找的數,把它寫在分支的前面

left = mid +

1else

: right = mid

# 走到這裡是因為【邏輯 1】的反面,因此一定能找到第 1 個大於等於 nums[i] 的元素,因此無需再單獨判斷

tail[left]

= nums[i]

return

len(tail)

LeetCode300 最長上公升子串行

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。示例 輸入 10,9,2,5,3,7,101,18 輸出 4解釋 最長的上公升子串行是 2,3,7,101 它的長度是4。說明 題目分析 方法一 動態規劃,用dp i 表示以nums i 結尾的最長上公升子串行。那麼如何求dp i 呢,只要看n...

Leetcode 300 最長上公升子串行

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。示例 輸入 10,9,2,5,3,7,101,18 輸出 4解釋 最長的上公升子串行是 2,3,7,101 它的長度是4。說明 高階 你能將演算法的時間複雜度降低到 o n log n 嗎?解題思路 1.普通演算法 動態規劃。假設陣列的前n個數...

leetcode 300 最長上公升子串行

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。示例 輸入 10,9,2,5,3,7,101,18 輸出 4解釋 最長的上公升子串行是 2,3,7,101 它的長度是4。說明 高階 你能將演算法的時間複雜度降低到 o n log n 嗎?解法1 動態規劃空間複雜度o n 時間複雜度o n 2...