1. 程式人生 > >Min Stack 解題報告

Min Stack 解題報告

Min Stack

Description

Implement a stack with min() function, which will return the smallest number in the stack.

It should support push, pop and min operation all in O(1) cost.

Notice

min operation will never be called if there is no number in the stack.

Example

push(1)
pop()   // return 1
push(2) push(3) min() // return 2 push(1) min() // return 1

實現思路

對於實現一個最小棧,我們不能簡單地維護一個最小元素,因為當彈出最小元素後,我們需要找出第2小的作為當前的最小,故因此我們應該額外維護一個棧,裡面放的是一系列最小元素。
具體實現原理是,每當我們彈入一個元素到棧裡,判斷它是否比最小棧的棧頂元素小,如果是,就彈入棧裡,最小棧從棧頂到棧底應該是一個從小到大排列的序列。而在我們取出元素的時候,再判斷取出的是否等於最小棧棧頂元素(即是否為當前棧裡的最小元素)。如果是,就彈出最小棧棧頂元素。
通過此機制,我們維護了一個最小棧,舉個例子,我們依次彈入以下元素:
4、5、6、2、3、1
則最小棧為:
4、2、1,對應下表:

普通棧 最小棧
4 4
4、5 4
4、5、6 4
4、5、6、2 4、2
4、5、6、2、3 4、2
4、5、6、2、3、1 4、2、1

彈出時,序列彈出順序為1、3、2、6、5、4
時序對應下表:

普通棧 最小棧
4、5、6、2、3、1 4、2、1
4、5、6、2、3 4、2
4、5、6、2 4、2
4、5、6 4
4、5 4
4 4

從彈入、彈出的每一過程看,我們的操作,都確保了最小棧的棧頂元素,都是普通棧中的最小元素

根據此思路,求解方法如下:

public class MinStack {

    private Stack<Integer> minStack;
    private Stack<Integer> stack;
    public MinStack() {
        this.minStack = new Stack<>();
        this.stack = new Stack<>();
    }

    public void push(int number) {
        stack.push(number);
        if(minStack.isEmpty() || minStack.peek() >= number){
            minStack.push(number);
        }
    }

    public int pop() {
        int number = stack.pop();
        if(number == minStack.peek()){
            minStack.pop();
        }
        return number;
    }

    public int min() {
        return minStack.peek();        
    }
}