Min Stack -- LeetCode
阿新 • • 發佈:2018-11-16
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
原題連結: https://oj.leetcode.com/problems/min-stack/這道題是關於棧的題目,實現一個棧的基本功能,外加一個獲得最小元素的操作。正常情況下top,pop和push操作都是常量時間的,而主要問題就在於這個getMin上面,如果遍歷一遍去找最小值,那麼getMin操作就是O(n)的,既然出出來了這道題就肯定不是這麼簡單的哈。比較容易想到就是要追溯這個最小值,在push的時候維護最小值,但是如果pop出最小值的時候該如何處理呢,如何獲得第二小的值呢?如果要去尋找又不是常量時間了。解決的方案是再維護一個棧,我們稱為最小棧,如果遇到更小的值則插入最小棧,否則就不需要插入最小棧(注意這裡正常棧是怎麼都要插進去的)。這裡的正確性在於,如果後來得到的值是大於當前最小棧頂的值的,那麼接下來pop都會先出去,而最小棧頂的值會一直在,而當pop到最小棧頂的值時,一起出去後接下來第二小的就在pop之後最小棧的頂端了。如此push時最多插入兩個棧一個元素,是O(1),top是取正常棧頂,自然是O(1),而pop時也是最多丟擲兩個棧的棧頂元素,O(1)。最後getMin只需要peek最小棧頂棧頂即可,所以仍是O(1),實現了所有操作的常量操作,空間複雜度是O(n),最小棧的大小。程式碼如下:
class MinStack { ArrayList<Integer> stack = new ArrayList<Integer>(); ArrayList<Integer> minStack = new ArrayList<Integer>(); public void push(int x) { stack.add(x); if (minStack.isEmpty() || minStack.get(minStack.size()-1)>=x) { minStack.add(x); } } public void pop() { if (stack.isEmpty()) { return; } int elem = stack.remove(stack.size()-1); if(!minStack.isEmpty() && elem == minStack.get(minStack.size()-1)) { minStack.remove(minStack.size()-1); } } public int top() { if(!stack.isEmpty()) return stack.get(stack.size()-1); return 0; } public int getMin() { if(!minStack.isEmpty()) return minStack.get(minStack.size()-1); return 0; }}
這道題在理清思路之後程式碼還是比較簡單的,這裡用ArrayList來實現棧,當然也可以用連結串列,不過對於時間複雜度要求比較高,所以重點是想出維護最小棧頂做法,屬於比較考察站的性質的題目,是很不錯的面試題目,在面經中也經常出現。