【DW1月-力扣刷題】Task03 單調棧

參考鏈接:https://github.com/itcharge/LeetCode-Py

一、簡介

單調棧(Monotone Stack):一種特殊的棧。在棧的「先進后出」規則基礎上,要求「從棧頂到棧底的元素是單調遞增(或者單調遞減)」。其中滿足從棧頂到棧底的元素是單調遞增的棧,叫做「單調遞增棧」。滿足從棧頂到棧底的元素是單調遞減的棧,叫做「單調遞減棧」。

1.1 單調遞增棧

單調遞增棧:只有比棧頂元素小的元素才能直接進棧,否則需要先將棧中比當前元素小的元素出棧,再將當前元素入棧。
這樣就保證了:棧中保留的都是比當前入棧元素大的值,并且從棧頂到棧底的元素值是單調遞增的。
單調遞增棧的入棧、出棧的過程:

  • 假設當前進棧元素為 x,如果棧頂元素大于 x,則直接入棧。
  • 否則從棧頂開始遍歷棧中元素,把小于 x 或者等于 x 的元素彈出棧,直到遇到一個大于 x 的元素為止,然后再把 x 壓入棧中。

實例:

  • 數組元素:[2, 7, 5, 4, 6, 3, 4, 2],遍歷順序為從左到右。


    image.png
12.jpg

最終棧中元素為 [7, 6, 4, 2]。因為從棧頂(右端)到棧底(左側)元素的順序為 2, 4, 6, 7,滿足遞增關系,所以這是一個單調遞增棧。

1.2 單調遞減棧

單調遞減棧:只有比棧頂元素大的元素才能直接進棧,否則需要先將棧中比當前元素大的元素出棧,再將當前元素入棧。
這樣就保證了:棧中保留的都是比當前入棧元素小的值,并且從棧頂到棧底的元素值是單調遞減的。
單調遞減棧的入棧、出棧的過程:

  • 假設當前進棧元素為 x,如果棧頂元素大于 x,則直接入棧。
  • 否則從棧頂開始遍歷棧中元素,把大于 x 或者等于 x 的元素彈出棧,直到遇到一個小于 x 的元素為止,然后再把 x 壓入棧中。

實例:

  • 數組元素:[4, 3, 2, 5, 7, 4, 6, 8],遍歷順序為從左到右。


    image.png

    image.png

    最終棧中元素為 [2, 4, 6, 8]。因為從棧頂(右端)到棧底(左側)元素的順序為 8, 6, 4, 2,滿足遞減關系,所以這是一個單調遞減棧。

二、單調棧適用場景

單調棧可以在時間復雜度為 O(n) 的情況下,求解出某個元素左邊或者右邊第一個比它大或者小的元素。
所以單調棧一般用于解決一下幾種問題:

  • 尋找左側第一個比當前元素大的元素
  • 尋找左側第一個比當前元素小的元素
  • 尋找右側第一個比當前元素大的元素
  • 尋找右側第一個比當前元素小的元素

2.1 尋找左側第一個比當前元素大的元素

從左到右遍歷元素,構造單調遞增棧(從棧頂到棧底遞增):一個元素左側第一個比它大的元素就是將其「插入單調遞增棧」時的棧頂元素。如果插入時的棧為空,則說明左側不存在比當前元素大的元素。

2.2 尋找左側第一個比當前元素小的元素

從左到右遍歷元素,構造單調遞減棧(從棧頂到棧底遞減):一個元素左側第一個比它小的元素就是將其「插入單調遞減棧」時的棧頂元素。如果插入時的棧為空,則說明左側不存在比當前元素小的元素。

2.3 尋找右側第一個比當前元素大的元素

從左到右遍歷元素,構造單調遞增棧(從棧頂到棧底遞增):一個元素右側第一個比它大的元素就是將其「彈出單調遞增棧」時即將插入的元素。如果該元素沒有被彈出棧,則說明右側不存在比當前元素大的元素。

從右到左遍歷元素,構造單調遞增棧(從棧頂到棧底遞增):一個元素左側第一個比它大的元素就是將其「插入單調遞增棧」時的棧頂元素。如果插入時的棧為空,則說明左側不存在比當前元素大的元素。

2.4 尋找右側第一個比當前元素小的元素

從左到右遍歷元素,構造單調遞減棧(從棧頂到棧底遞減):一個元素右側第一個比它小的元素就是將其「彈出單調遞減棧」時即將插入的元素。如果該元素沒有被彈出棧,則說明右側不存在比當前元素小的元素。

從右到左遍歷元素,構造單調遞減棧(從棧頂到棧底遞減):一個元素右側第一個比它小的元素就是將其「插入單調遞減棧」時的棧頂元素。如果插入時的棧為空,則說明右側不存在比當前元素小的元素。

小結

  • 無論哪種題型,都建議從左到右遍歷元素。
  • 查找 「比當前元素大的元素」 就用 單調遞增棧,查找「比當前元素小的元素」就用 單調遞減棧。
  • 從 「左側」 查找就看 「插入棧」 時的棧頂元素,從 「右側」 查找就看 「彈出棧」 時即將插入的元素。

三、單調棧模板

3.1 單調遞增棧模板

def monotoneIncreasingStack(nums):
    stack = []
    for num in nums:
        while stack and num >= stack[-1]:
            stack.pop()
        stack.append(num)

3.2 單調遞減棧模板

def monotoneDecreasingStack(nums):
    stack = []
    for num in nums:
        while stack and num <= stack[-1]:
            stack.pop()
        stack.append(num)

四、單調棧的應用

下一個更大元素、每日溫度等。

五、總結

本章節主要介紹了單調棧的類型、基礎理論、實現過程和使用場景。單調棧原理很簡單,就是按大小排成一列,但是不能小覷,它的操作不能一步到位,只能一步一步實現,而且不一定所有的數都能入棧,有些數可能被彈出去不能入棧。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,348評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,083評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,706評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,442評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,802評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,983評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,542評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,287評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,486評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,710評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,116評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,412評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,224評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,462評論 2 378

推薦閱讀更多精彩內容