演算法之單調棧與單調佇列

2021-09-26 07:31:10 字數 2879 閱讀 6711

單調佇列顧名思義就是具有單一單調性的佇列。

給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。

數列長度:n<=106,m<=n

數列為:6 4 10 10 8 6 4 2 12 14,求長度為3的數列段內的最大數,使用單調遞減棧。

(1)(6,0)入隊,此時隊列為(6,0)

(2)(4,1)入隊,此時隊列為(6,0) (4,1)

(3)(10,2)入隊,需要遞減,那麼(4,1) (6,0)需要出隊,此時隊列為(10,2)

(4)(10,3)入隊,需要遞減,那麼(10,2)需要出隊,此時隊列為(10,3)

(5)(8,4)入隊,此時隊列為(10,3) (8,4)

(6)(6,5)入隊,此時隊列為(10,3) (8,4) (6,5)

(7)(4,6)入隊,超長(10,3)出隊,此時隊列為(8,4) (6,5) (4,6)

(8)(2,7)入隊,超長(8,4)出隊,此時隊列為(6,5) (4,6) (2,7)

(9)(12,8)入隊,需要遞減,那麼(6,5) (4,6) (2,7)需要出隊,此時隊列為(12,8)

(9)(14,9)入隊,需要遞減,那麼(12,8)需要出隊,此時隊列為(14,9)

對於每次的輸出,就是佇列頭部的值,分別為:

6 6 10 10 10 10 8 6 12 14(注意開始時的最值)

最大值:佇列單調遞減,隊頭就是需要的最大值。

最小值:佇列單調遞增,隊頭就是需要的最小值。

單調棧顧名思義就是具有單一單調性的棧,在棧頂操作。

柱形圖中的最大矩形面積。

給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度為 1 。

求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。

以上是柱狀圖的示例,其中每個柱子的寬度為 1,給定的高度為[2,1,5,6,2,3]

圖中陰影部分為所能勾勒出的最大矩形面積,其面積為 10 個單位。

輸入: [2,1,5,6,2,3]

輸出: 10

該題使用單調棧,輔助乙個寬度表width,模擬如下:

(1)2入棧,width[top++] = 1,棧內元素2width=

(2)1即將入棧,1<2,2出棧,curwidth+=width[--top]==1,res = max(res , 2 * curwidth) == 2,1入棧,width[top++] = curwidth + 1 == 2,棧內元素1width=

(3)5>1,5入棧,width[top++] = 1,棧內元素1 5top=2width=

(4)6>5,6入棧,width[top++] = 1,棧內元素1 5 6top=3width=

(5)2即將入棧,2<6,6出棧,curwidth+=width[--top] == 1,res = max(2 , 6 * curwidth) == 6width=

2<5,5出棧,curwidth+=width[--top] == 2,res = max(6 , 5 * curwidth) == 10width=

;2入棧,width[top++] = curwidth + 1 == 3,棧內元素1 2width=

(8)3入棧,width[top++] = 1,棧內元素1 2 3width=

(8)資料為空,棧不為空,彈棧算棧內的資料。

(9)3出棧,curwidth+=width[--top] == 1,res = max(10 , 3 * curwidth) == 10width=

(10)2出棧,curwidth+=width[--top] == 4,res = max(10 , 2 * curwidth) == 10width=

(11)1出棧,curwidth+=width[--top] == 5,res = max(10 , 1 * curwidth) == 10width={}

單調佇列與單調棧

單調棧 單調棧,顧名思義,就是維持單調性 遞增或者遞減 的棧結構,如果新入棧的元素破壞了單調性,就彈出原先棧內元素,直到能夠滿足單調性 用途 它可以很方便地求出某個數的左邊或者右邊第乙個比它大或者小的元素,而且總時間複雜度o n 並且單調棧本身並不難實現 維護 每次入棧前先檢驗入棧後是否會破壞棧的單...

單調佇列與單調棧

線段樹等等容易tle,我們需要乙個o n 的演算法來解決這個問題。思路 可以看出,這個視窗是可以用乙個雙向佇列來模擬的,每當後方加入乙個數,都要從佇列尾部開始淘汰掉所有的小於它的數,保證佇列中每乙個數的後面,在視窗範圍內沒有大於等於它的數。當隊首元素不在視窗範圍時,隊首元素出隊。這樣操作後,隊內的元...

單調佇列與單調棧

線段樹等等容易tle,我們需要乙個o n 的演算法來解決這個問題。思路 可以看出,這個視窗是可以用乙個雙向佇列來模擬的,每當後方加入乙個數,都要從佇列尾部開始淘汰掉所有的小於它的數,保證佇列中每乙個數的後面,在視窗範圍內沒有大於等於它的數。當隊首元素不在視窗範圍時,隊首元素出隊。這樣操作後,隊內的元...