定義棧的資料結構,請在該型別中實現乙個能夠得到棧的最小元素的 min 函式在該棧中,呼叫 min、push 及 pop 的時間複雜度都是 o(1)。
示例:
minstack minstack =
newminstack()
;minstack.
push(-
2);minstack.
push(0
);minstack.
push(-
3);minstack.
min();
--> 返回 -
3.minstack.
pop();
minstack.
top();
--> 返回 0.
minstack.
min();
--> 返回 -
2.
單調棧的問題可以先從常規思路著手,然後挖掘出問題的一些性質
常規思路:普通棧的 push() 和 pop() 函式的複雜度為 o(1) ;而獲取棧最小值 min() 函式需要遍歷整個棧,複雜度為 o(n)。
本題難點: 將 min() 函式複雜度降為 o(1)o(1) ,可通過建立單調棧實現;
資料棧 a : 棧 a 用於儲存所有元素,保證入棧 push() 函式、出棧 pop() 函式、獲取棧頂 top() 函式的正常邏輯。
單調棧 b :棧 b 中儲存棧 a 中所有 非嚴格降序 的元素,則棧 a 中的最小元素始終對應棧 b 的棧頂元素,即 min() 函式只需返回棧 b 的棧頂元素即可。
因此,只需設法維護好 棧 b 的元素,使其保持非嚴格降序(從棧底到棧頂),即可實現 min() 函式的 o(1) 複雜度。
push(x):
先將元素壓入棧a,如果棧b為空,直接壓入棧b即可,否則只有該元素比當前棧頂元素更小(或者相等)的時候,才會被壓入棧b中。這樣就可以保證棧b從棧底到棧頂時單調遞減的。
疑惑點:為什麼只有插入的元素比當前棧頂元素更小的時候,才會被壓入棧b中。
我們不妨假設棧b的棧頂元素就是我們的最小值min,此時這個最小值min也位於棧a裡面,當插入元素x時。
如果x比棧頂元素大,那麼就無須插入棧b中,此時,棧a的最小值仍然是min,由於棧是後進先出的,所以x先於min彈出棧,在沒有插入其它更小的元素之前,仍然能保持棧中最小元素是min,直到min被彈出為止。所以成立
如果x比棧頂元素小,那麼就把x插入棧b中,此時棧a的最小值是x,當x彈出後,棧b中的元素x也將被彈出,此時min成為了棧a的最小值。
關鍵點是棧b中的「最小值」被彈出的順序與這些「最小值」在棧a中的彈出順序是相同的。
pop():
先將棧a中的棧頂元素彈出,如果該元素是棧b的棧頂元素,則棧b的棧頂元素也將被彈出
min()
直接返回棧b的棧頂元素即可。
top()
返回棧a的棧頂元素即可。
class
minstack
public
void
push
(int x)
}public
void
pop()}
public
inttop()
public
intmin()
return0;
}}
劍指Offer 30 包含min函式的棧
定義棧的資料結構,請在該型別中實現乙個能夠得到棧最小元素的min函式。在該棧中,呼叫min push及pop的時間複雜度都是o 1 首先觀察到min的時間複雜度是o 1 所以不可能是在我們呼叫min的時候再去計算棧中元素的最小值,最小值一定是提前儲存好的。其次最小值必須隨著push和pop更新,也就...
劍指offer 30 包含min函式的棧
這道題的題目可以描述為 定義棧的資料結構,請在該型別中實現乙個能夠得到棧的最小元素的min函式,在該棧中,呼叫min,push以及pop的時間複雜度都是o 1 typedef int datatype define maxsize 100 typedef structstack void stack...
劍指offer 30 包含min函式的棧
定義棧的資料結構,請在該型別中實現乙個能夠得到棧中所含最小元素的min函式 時間複雜度應為o 1 常規思路的問題 如果每次push對棧排序,讓整個棧保持有序狀態,實際上已經破壞了棧這個結構,而且複雜度肯定不是o 1 如果用乙個變數記錄最小值,當這個最小值被pop出去後,找不到次小值。當然你也可以找個...