【learning】 單調隊列與單調棧用法詳解


1、單調棧

單調棧是指一個棧內部的元素具有嚴格單調性的一種數據結構,分為單調遞增棧和單調遞減棧。

 

其具有以下兩個性質:

1,滿足棧底到棧頂的元素具有嚴格單調性。

2,滿足棧的先進后出特性,越靠近棧頂的元素越后出棧。

 

 

元素進棧過程:

對於一個單調遞增棧來說,若當前進棧的元素為a,如果a<棧頂元素,則直接將a進棧。

如果a≥棧頂元素,則不斷將棧頂元素出棧,直到滿足a<棧頂元素。

 

模擬一個數列構造一個單調遞增棧

進棧元素分別為3,4,2,6,4,5,2,3。

圖片所示過程即為進棧過程。

 

實現單調棧STL棧和手寫棧均可。

 

2,單調隊列。

單調隊列與單調棧及其相似,把單調棧先進后出的性質改為先進先出既可。 

元素進隊列的過程對於單調遞增隊列。

對於一個元素a,如果a>隊尾元素,那么直接將a扔進隊列,如果a≥隊尾元素,則將隊尾元素出隊列,直到滿足 a>隊尾元素即可。

 

實現用STL的雙端隊列即可(我好像一直都是手寫的)

由於雙端隊列即可以在隊頭操作,也可以在隊尾操作,那么這樣的性質就彌補了單調棧只能在一邊操作的不足。可以使得其左邊也有一定的限制。

 

3,時間復雜度分析

對於每個元素,其有且僅有一次插入,最多出現一次刪除,故其時間復雜度為O(n)。

 

練習:

給你n個數,讓你在這n個數中選出連續的m個數(m≤n),使這m個數的極差最小,若存在多個區間使得極差均最小,輸出最靠前的區間。

很顯然,$n≤10^4$時暴力明顯可做,$n≤10^6$時通過線段樹也可做,那如果n去到$10^7$呢?

 

我們考慮用單調隊列維護區間$[i,i+m-1]$的最小值和最大值,以下篇幅以維護最大值舉例。

首先,我們把前m個數扔進一個單調遞增隊列中,在扔進去的同時把這些數所對應的下邊也扔進去。顯然隊頭的數字即為區間[1,m]最大的數。

考慮基於[1,m]的數據去更新[2,m+1]的最大值。若第一個數依然存在於隊列中(很顯然若存在僅可能位於隊尾),將這個數刪除,然后將第m+1個數插入改單調隊列。顯然隊尾數字即為區間[2,m+1]的最大值。

重復該過程n-m+1次即可,顯然時間復雜度為O(n)。

練習:bzoj1047

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM