劍指Offer30 包含min函式的棧 單調棧

2021-10-20 01:25:50 字數 1757 閱讀 6531

定義棧的資料結構,請在該型別中實現乙個能夠得到棧的最小元素的 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出去後,找不到次小值。當然你也可以找個...