1. 程式人生 > >Java架構-面試演算法:計算堆疊當前元素的最大值

Java架構-面試演算法:計算堆疊當前元素的最大值

有一道堆疊相關演算法題,我被面試過兩次以上,看似其在演算法面試中出現的概率很高,由此值得我們好好分析下。題目是這樣的:

對於堆疊的常用操作有, pop 彈出堆疊頂部的元素;push 向堆疊壓入一個元素;peek 獲得堆疊頂部的元素值,但不彈出堆疊。現在要去你增加一個操作max, 它的作用是返回堆疊當前所有元素中值最大的那個,例如堆疊當前元素有:
stack: 5,4,2,3
那麼max() 返回的值就是5. 假設向堆疊繼續推入元素後,情況如下:

stack: 5, 4, 2, 3, 6, 1, 10, 8

那麼呼叫max() 得到的元素為10.

假設我們現在我們採取pop操作,彈出頂部兩個元素,那麼堆疊情況如下:

stack: 5, 4, 2, 3, 6, 1

顯然此時max 操作返回的元素是6。

請給出一個時間複雜度為O(1)的演算法,實現max操作。

這道題一個麻煩處在於,如果堆疊僅僅是壓入元素,那麼返回最大值是很容易的,只要把當前壓入元素的最大值記下來就可以了。問題在於,堆疊還有彈出操作,當彈出後,堆疊當前的最大元素可能就會不斷的發生變化。如果是壓入操作和彈出操作交替進行的話,那麼情況就更復雜了。

解決這個問題的演算法如下:
1, 每次壓入元素是,用一個變數maxVal, 記錄堆疊當前元素的最大值。
2, 建立一個新堆疊maxStack,當壓入元素的值大於當前元素的最大值時,把該元素壓入maxStack.
3, 彈出一個元素時,如果彈出的元素是當前最大值,那麼把maxStack頂部的元素也彈出,然後把maxValue設定成maxStack的頂部元素。
4,執行max()操作時,可以直接返回maxValue, 或是maxStack堆疊的頂部元素。

不難看出,上述操作使得元素壓入時,maxValue 與 maxStack頂部元素保持一致,當元素彈出時,如果彈出的是當前最大值,那麼步驟3把maxValue的值設定成maxStack的頂部元素,因此,無論是壓入還是彈出操作,maxValue與maxStack的始終保持一致。

同時,當只有壓入元素大於當前堆疊元素的最大值時,新元素才會壓入maxStack,這就保證了maxStack堆疊頂部的元素就是當前堆疊中所有元素最大的一個。

上面演算法,執行max()操作時,只需要把maxStack頂部元素彈出或直接返回maxValue,因此時間複雜度是O(1), 在特殊情況下,例如所有元素是升序壓入堆疊的,比如壓入的元素為:1,2, 3, 4.那麼這些元素除了壓入正常堆疊外,還得全部壓入maxStack, 因此演算法的空間複雜度是O(N).

我們看看具體程式碼的實現:

程式碼實現簡單,基本上根據演算法步驟來實現,我們再看看主入口處的程式碼:

執行結果如下:

稍微檢測下便可以發現,程式碼給出的結果是正確的,更多更詳實的講解和除錯演示過程,請大家參考視訊。

歡迎大家和我一起學習交流構建Java雲架構,我這邊會將近期研發的Java雲架構的搭建過程和精髓記錄下來,幫助更多有興趣研發Java高階架構的朋友,大家來一起探討Java高階架構的搭建過程及如何運用於企業專案。

我本人邀約各大BATJ架構大牛共創Java高階架構交流社群群,(群號:673043639)致力於免費提供Java架構行業交流平臺,通過這個平臺讓大家相互學習成長,提高技術,讓自己的水平進階一個檔次,成功通往Java架構技術大牛或架構師發展。

希望此文能幫到大家的同時,也聽聽大家的觀點。歡迎留言討論,加關注,分享你的高見!持續更新!

To-陌霖Java架構

分享網際網路最新文章 關注網際網路最新發展