1. 程式人生 > >Min Stack -- LeetCode

Min Stack -- LeetCode

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!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來實現棧,當然也可以用連結串列,不過對於時間複雜度要求比較高,所以重點是想出維護最小棧頂做法,屬於比較考察站的性質的題目,是很不錯的面試題目,在面經中也經常出現。           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述