單調棧問題

1:單調棧的概述

首先先了解一下什麼是單調棧(Monotonic stack),他有什麼用途,我們在解決什麼問題的時候可以用到單調棧? ​ 我們都知道棧(stack)是很簡單的一種數據結構,先進後出的邏輯順序,符合某些問題的特點,比如說函數調用棧。單調棧顧名思義就是棧,只是利用了一些巧妙的邏輯,使得每次新元素入棧後,棧內的元素都保持有序(單調遞增或單調遞減)。單調棧一般用來解決比當前元素更大或者更小的下一個元素問題,也即是 next greater element 或者next smaller element 相關問題,因為下一個更大或者下一個更小的元素正好符合棧的基本定義,再加上單調性,就可以在O(n)時間複雜度內解決這類問題了,LeetCode中比較典型的單調棧問題如下。

2:LeetCode相關經典的題目

第一部分:

402. 移掉 K 位數字

316. 去除重複字母

321. 拼接最大數

84. 柱狀圖中最大的矩形

85. 最大矩形

第二部分:

456. 132 模式

496. 下一個更大元素 I

503. 下一個更大元素 II

3:解決單調棧問題的一般程式碼模板

for _, v := range num {
   //當有該元素入棧時,不符合棧中單調性的時候,彈出棧頂元素,一直到滿足單調性為止
for k > 0 && !stack.isEmpty() && v < stack.peek() {
k--
stack.pop()
}
stack.push(v)
}

4:解決單調棧問題的一般解題思路

首先,我們要明白單調棧棧可以解決什麼樣的問題,這個雖然已經在開頭說過了,再次還要重點強調一下,單調棧是為了解決下一個比當前元素大或者小的問題的,那麼當我們遇到一個類似問題的時候我們要對比著單調棧已有的性質和解決方案分析問題,仔細的分析一下我們遇到的問題是否符合單調棧相關的性質(如果這個分析不出來的話,那就說明我們對單調棧相關的問題還不是太熟悉,按照LeetCode上面的問題類型多加練習和總結,一般在遇到類似相關問題就可以分析出此類問題應該用什麼樣的方式去解決),如果確定是屬於單調棧的問題那麼,我們就可以努力往單調棧的思路上去靠,然後利用單調棧的性質去解決此類問題。

當然,我們解決問題的時候可能問題涉及的不只有單調棧這一個知識點,這就需要我們使用單調棧結合其他的知識來解決問題了,然而能熟練使用單調棧解決問題也不是解決一道或者兩道問題就能深刻理解的,那麼後續就需要我們多加練習和總結來鞏固我們所學的知識點,為利用單調棧和其他知識點結合解決更複雜的問題夯實基礎。

(以上的LeetCode中的問題比較經典,都是和單調棧相關的問題,還有和利用其他知識綜合解決的問題,最好是按照順序做一下,題解LeetCode已經寫的非常的詳細了,再次不多敘述關於具體題目的題解,本篇只是文檔單純的說一下關於單調棧問題的一些總結,具體的題解和參考LeetCode的官方題解)

Tags: