日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

如何实现可以获取最小值的栈?

發(fā)布時間:2025/3/21 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何实现可以获取最小值的栈? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

小史是一個應(yīng)屆生,雖然學(xué)的是電子專業(yè),但是自己業(yè)余時間看了很多互聯(lián)網(wǎng)與編程方面的書,一心想進(jìn)BAT。

今天他又去BAT中的一家面試了。

簡單的自我介紹后,面試官給了小史一個問題。

?

面試現(xiàn)場

題目:我現(xiàn)在需要實(shí)現(xiàn)一個棧,這個棧除了可以進(jìn)行普通的push、pop操作以外,還可以進(jìn)行g(shù)etMin的操作,getMin方法被調(diào)用后,會返回當(dāng)前棧的最小值,你會怎么做呢?你可以假設(shè)棧里面存的都是int整數(shù)。

?

小史熟練地把代碼寫了出來。

?

public?class?MinStack?{private?List<Integer>?data?=?new?ArrayList<Integer>();private?List<Integer>?mins?=?new?ArrayList<Integer>();public?void?push(int?num)?{data.add(num);if(mins.size()?==?0)?{//?初始化minsmins.add(num);}?else?{//?輔助棧mins每次push當(dāng)時最小值int?min?=?getMin();if?(num?>=?min)?{mins.add(min);}?else?{mins.add(num);}}}public?int?pop()?{//?棧空,異常,返回-1if(data.size()?==?0)?{return?-1;}//?pop時兩棧同步popmins.remove(mins.size()?-?1);return?data.remove(data.size()?-?1);}public?int?getMin()?{//?棧空,異常,返回-1if(mins.size()?==?0)?{return?-1;}//?返回mins棧頂元素return?mins.get(mins.size()?-?1);}}

(友情提示:可左右滑動)

?

請教大神

小史回到學(xué)校,把面試的情況和計(jì)算機(jī)學(xué)院的呂老師說了一下。

?

?

異常情況處理

呂老師:面試官已經(jīng)提出了你的異常處理有點(diǎn)問題,當(dāng)棧內(nèi)為空的時候,你返回-1,但是如果用戶push過-1,那么你返回-1的時候,是用戶push進(jìn)來的值,還是棧為空,就不得而知了。

?

小史咬咬牙:那就再定義一個類,里面包括一個int的data和一個boolean的isSuccess,正常情況下isSuccess是true,棧為空的話,isSuccess是false。這樣就能區(qū)分開了吧?

小史突然一拍大腿:對哦,我可以用一個包裝類Integer來定義返回值,如果是空,就代表?xiàng)榭站托辛恕K蚷nt的區(qū)別就是它多了一個null,正好用來返回異常情況。

?

呂老師:嗯,越來越好,但是還是有點(diǎn)問題。你并沒有站在使用者的角度考慮問題。使用你這個棧的人,在pop的時候,他并不知道可能返回null,如果他不做判斷,后面的代碼就可能拋出空指針了。

呂老師發(fā)來一個表情。

呂老師:沒錯,最關(guān)鍵的是,你顯式拋出異常,如果使用者不捕獲,那么編譯就會報錯,這樣就把錯誤暴露在編譯階段,并且不需要和任何人商量所謂的特殊返回值了。

(碼農(nóng)翻身老劉注:拋出的異常應(yīng)該是checked還是unchecked? 這個地方大家可以討論下!)

?

算法優(yōu)化

呂老師一眼看穿了小史的心思。

?

小史想了想:明白了,我可以在push的時候判斷一下,如果比最小值還大,就不加入輔助棧。pop的時候,如果不是最小值,輔助棧就不出棧。這樣一來,輔助棧就不會有大量重復(fù)元素了。

小史:push的時候進(jìn)行判斷,如果數(shù)值比當(dāng)前最小值大,就不動mins棧了,這樣mins棧中不會保存大量冗余的最小值。pop的時候同樣進(jìn)行判斷,只有pop出的數(shù)就是當(dāng)前最小值的時候,才讓mins出棧。

?

小史:如果push一個和最小值相等的元素,還是要入mins棧。不然當(dāng)這個最小值pop出去的時候。data中還會有一個最小值元素,而mins中卻已經(jīng)沒有最小值元素了。

?

?

小史:mins棧中改存最小值在data數(shù)組中的索引。這樣一來,當(dāng)push了與最小值相同元素的時候,就不需要動mins棧了。而pop的時候,pop出的元素的索引如果不是mins棧頂元素,mins也不出棧。同時,獲取最小值的時候,需要拿到mins棧頂元素作為索引,再去data數(shù)組中找到相應(yīng)的數(shù)作為最小值。

理解了算法之后,小史的代碼寫起來也是非常快,不一會兒就寫好了:

public?class?MinStack?{private?List<Integer>?data?=?new?ArrayList<Integer>();private?List<Integer>?mins?=?new?ArrayList<Integer>();public?void?push(int?num)?{data.add(num);if(mins.size()?==?0)?{//?初始化minsmins.add(0);}?else?{//?輔助棧mins?push最小值的索引int?min?=?getMin();if?(num?<?min)?{mins.add(data.size()?-?1);}}}public?int?pop()?{//?棧空,拋出異常if(data.size()?==?0)?{throw?new?EmptyStackException();}//?pop時先獲取索引int?popIndex?=?data.size()?-?1;//?獲取mins棧頂元素,它是最小值索引int?minIndex?=?mins.get(mins.size()?-?1);//?如果pop出去的索引就是最小值索引,mins才出棧if(popIndex?==?minIndex)?{mins.remove(mins.size()?-?1);}return?data.remove(data.size()?-?1);}public?int?getMin()?{//?棧空,拋出異常if(data.size()?==?0)?{throw?new?EmptyStackException();}//?獲取mins棧頂元素,它是最小值索引int?minIndex?=?mins.get(mins.size()?-?1);return?data.get(minIndex);} }

(友情提示:可左右滑動)

?

?

小史的疑惑

吃飯的時候,小史提出了心中埋藏已久的疑惑。

呂老師:數(shù)據(jù)結(jié)構(gòu)和算法的設(shè)計(jì)是一個程序員的內(nèi)功,工作時雖然用不到這么細(xì),但是你在學(xué)習(xí)其他知識的底層原理的時候,到處都是數(shù)據(jù)結(jié)構(gòu)和算法。

總結(jié)

以上是生活随笔為你收集整理的如何实现可以获取最小值的栈?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。