結構pop 特殊資料結構 單調佇列

2021-10-14 23:00:58 字數 2563 閱讀 9221

239.滑動視窗最大值

-----------

前文講了一種特殊的資料結構「單調棧」monotonic stack,解決了一類問題「next greater number」,本文寫乙個類似的資料結構「單調佇列」。

也許這種資料結構的名字你沒聽過,其實沒啥難的,就是乙個「佇列」,只是使用了一點巧妙的方法,使得佇列中的元素單調遞增(或遞減)。這個資料結構有什麼用?可以解決滑動視窗的一系列問題。

ps:我認真寫了 100 多篇原創,手把手刷 200 道力扣題目,全部發布在 labuladong的演算法小抄,持續更新。建議收藏,按照我的文章順序刷題,掌握各種演算法套路後投再入題海就如魚得水了。

看一道 leetcode 題目,難度 hard:

在一堆數字中,已知最值,如果給這堆數新增乙個數,那麼比較一下就可以很快算出最值;但如果減少乙個數,就不一定能很快得到最值了,而要遍歷所有數重新找最值。

回到這道題的場景,每個視窗前進的時候,要新增乙個數同時減少乙個數,所以想在 o(1) 的時間得出新的最值,就需要「單調佇列」這種特殊的資料結構來輔助了。

乙個普通的佇列一定有這兩個操作:

class queue
乙個「單調佇列」的操作也差不多:

class monotonicqueue
當然,這幾個 api 的實現方法肯定跟一般的 queue 不一樣,不過我們暫且不管,而且認為這幾個操作的時間複雜度都是 o(1),先把這道「滑動視窗」問題的解答框架搭出來:

這個思路很簡單,能理解吧?下面我們開始重頭戲,單調佇列的實現。

首先我們要認識另一種資料結構:deque,即雙端佇列。很簡單:

class deque
而且,這些操作的複雜度都是 o(1)。這其實不是啥稀奇的資料結構,用鍊錶作為底層結構的話,很容易實現這些功能。

「單調佇列」的核心思路和「單調棧」類似。單調佇列的 push 方法依然在隊尾新增元素,但是要把前面比新元素小的元素都刪掉:

class monotonicqueue 

};

你可以想象,加入數字的大小代表人的體重,把前面體重不足的都壓扁了,直到遇到更大的量級才停住。

ps:我認真寫了 100 多篇原創,手把手刷 200 道力扣題目,全部發布在 labuladong的演算法小抄,持續更新。建議收藏,按照我的文章順序刷題,掌握各種演算法套路後投再入題海就如魚得水了。

如果每個元素被加入時都這樣操作,最終單調佇列中的元素大小就會保持乙個單調遞減的順序,因此我們的 max() api 可以可以這樣寫:

int max()
pop() api 在隊頭刪除元素 n,也很好寫:

void pop(int n)
之所以要判斷data.front() == n,是因為我們想刪除的隊頭元素 n 可能已經被「壓扁」了,這時候就不用刪除了:

至此,單調佇列設計完畢,看下完整的解題**:

class monotonicqueue 

int max()

void pop(int n)

};vectormaxslidingwindow(vector& nums, int k) else

}return res;

}

三、演算法複雜度分析讀者可能疑惑,push 操作中含有 while 迴圈,時間複雜度不是 o(1) 呀,那麼本演算法的時間複雜度應該不是線性時間吧?

單獨看 push 操作的複雜度確實不是 o(1),但是演算法整體的複雜度依然是 o(n) 線性時間。要這樣想,nums 中的每個元素最多被 push_back 和 pop_back 一次,沒有任何多餘操作,所以整體的複雜度還是 o(n)。

空間複雜度就很簡單了,就是視窗的大小 o(k)。

四、最後總結

有的讀者可能覺得「單調佇列」和「優先順序佇列」比較像,實際上差別很大的。

單調佇列在新增元素的時候靠刪除元素保持佇列的單調性,相當於抽取出某個函式中單調遞增(或遞減)的部分;而優先順序佇列(二叉堆)相當於自動排序,差別大了去了。

趕緊去拿下 leetcode 第 239 道題吧~

_____________

資料結構 單調棧,單調佇列

乙個單調遞增棧的例子 進棧元素分別為3,4,2,6,4,5,2,3 第i步操作結果1 3進棧3 23出棧,4進棧43 2進棧4 2 42 4出棧,6進棧65 4進棧6 4 64出棧,5進棧 6 57 2進棧6 5 2 82出棧,3進棧 6 5 3 對於乙個元素i 在 尾部 新增元素 while r ...

資料結構基礎 單調佇列

單調佇列一般是具有單調性的佇列,單調佇列有單調遞增和單調遞減兩種,一般來講,佇列的隊首是整個佇列的最大值或最小值,它的思想也是在決策集合 佇列 中及時排除一定不是最優解的選擇。單調佇列是優化動態規劃的乙個重要手段。具體實現步驟 維護單調單調遞增佇列 若隊列為空,將s i 從隊尾入隊。若佇列不為空,將...

資料結構之單調佇列

dev.c 資料結構之單調棧 從數學上來講,函式的單調性也可以叫做函式的增減性。當函式f x 的自變數在其定義區間內增大 或減小 時,函式值f x 也隨著增大 或減小 則稱該函式為在該區間上具有單調性。換句話來說,函式的單調性就是在區間內的自變數只增或只減。我們說,數學中函式在一段區間內自變數只增或...