Leecode 300 最長上公升子串行

2021-10-03 20:56:10 字數 1372 閱讀 2793

題目描述

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

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

輸出: 4

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

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

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

高階: 你能將演算法的時間複雜度降低到 o(n log n) 嗎?

貪心 + 二分查詢

思路與演算法

考慮乙個簡單的貪心,如果我們要使上公升子串行盡可能的長,則我們需要讓序列上公升得盡可能慢,因此我們希望每次在上公升子串行最後加上的那個數盡可能的小。

基於上面的貪心思路,我們維護乙個陣列 d[i],表示長度為 i的最長上公升子串行的末尾元素的最小值,用 len 記錄目前最長上公升子串行的長度,起始時 len 為 1,d[1]=nums[0]。

同時我們可以注意到 d[i]是關於 i 單調遞增的。因為如果 d[j]≥d[i] 且 j < i,我們考慮從長度為 ii的最長上公升子串行的末尾刪除 i-j個元素,那麼這個序列長度變為 j ,且第 j個元素 x(末尾元素)必然小於 d[i],也就小於 d[j]。那麼我們就找到了乙個長度為 j 的最長上公升子串行,並且末尾元素比 d[j] 小,從而產生了矛盾。因此陣列 d 的單調性得證。

我們依次遍歷陣列 nums 中的每個元素,並更新陣列 d 和 len 的值。如果 nums[i]>d[len] 則更新 len=len+1,否則在 d[1…len]中找滿足 d[i−1]d[len] ,則直接加入到 d 陣列末尾,並更新 len=len+1;

否則,在 dd 陣列中二分查詢,找到第乙個比 nums[i] 小的數 d[k] ,並更新 d[k+1]=nums[i]。

以輸入序列 [0, 8, 4, 12, 2][0,8,4,12,2] 為例:

第一步插入 0,d = [0];

第二步插入 8,d = [0, 8];

第三步插入 4,d = [0, 4];

第四步插入 12,d = [0, 4, 12];

第五步插入 2,d=[0,2,12]。

最終得到最大遞增子串行長度為 3。

300 最長上公升子串行

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

300 最長上公升子串行

建立dp表,dp i 表示含第i個數字的最長上公升子串行的長度 求dp i 時,向前遍歷找出比i元素小的元素j,則動態方程為dp i max dp i dp j 1 class solution object def lengthoflis self,nums size len nums if si...

300 最長上公升子串行

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。示例 輸入 10 9,2 5,3 7,101,18 輸出 4 解釋 最長的上公升子串行是 2,3,7,101 它的長度是 4。說明 可能會有多種最長上公升子串行的組合,你只需要輸出對應的長度即可。你演算法的時間複雜度應該為 o n2 高階 你能...