Min Stack -- LeetCode

原題連接:  https://oj.leetcode.com/problems/min-stack/
這道題是關於棧的題目,實現一個棧的基本功能,外加一個得到最小元素的操做。

正常狀況下top。pop和push操做都是常量時間的,而主要問題就在於這個getMin上面,假設遍歷一遍去找最小值,那麼getMin操做就是O(n)的,既然出出來了這道題就確定不是這麼簡單的哈。比較easy想到就是要追溯這個最小值。在push的時候維護最小值,但是假設pop出最小值的時候該怎樣處理呢,怎樣得到第二小的值呢?假設要去尋找又不是常量時間了。java

解決的方案是再維護一個棧,咱們稱爲最小棧,假設遇到更小的值則插入最小棧。不然就不需要插入最小棧(注意這裏正常棧是怎麼都要插進去的)。面試

這裏的正確性在於。假設後來獲得的值是大於當前最小棧頂的值的,那麼接下來pop都會先出去,而最小棧頂的值會一直在,而當pop到最小棧頂的值時,一塊兒出去後接下來第二小的就在pop以後最小棧的頂端了。如此push時最多插入兩個棧一個元素,是O(1)。top是取正常棧頂,天然是O(1)。而pop時也是最多拋出兩個棧的棧頂元素,O(1)。最後getMin僅僅需要peek最小棧頂棧頂就能夠。因此還是O(1)。實現了所有操做的常量操做。空間複雜度是O(n),最小棧的大小。代碼例如如下:post

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來實現棧,固然也可以用鏈表,只是對於時間複雜度要求比較高,因此重點是想出維護最小棧頂作法。屬於比較考察站的性質的題目,是很是不錯的面試題目,在面經中也經常出現。
相關文章
相關標籤/搜索