LeetCode115-最小棧

題目描述

設計一個支持 push ,pop ,top 操作,並能在常數時間內檢索到最小元素的棧。
push(x) —— 將元素 x 推入棧中。
pop() —— 刪除棧頂的元素。
top() —— 獲取棧頂元素。
getMin() —— 檢索棧中的最小元素。

分析

要在常數時間內獲取最小值,必定空間換時間,把當前棧的最小值用另外一個數據結構存起來。
最好的解決方法就是輔助棧——和數據棧一樣,只不過存的是當前棧的最小值。

同步輔助棧

輔助棧和數據棧大小一致:元素之間相互映射,數據棧元素對應的輔助棧元素是數據棧該元素到棧底的最小元素。

class LC_155 {
    private Stack<Integer> stack;
    private Stack<Integer> helper;
    public LC_155() {
        stack = new Stack<>();
        helper = new Stack<>();
    }

    public void push(int x) {
        stack.push(x);
        if (helper.isEmpty())helper.push(x);
        else helper.push(x>helper.peek()?helper.peek():x);
    }

    public void pop() {
        helper.pop();
        stack.pop();
    }

    public int top() {
        return stack.peek();
    }
    public int getMin() {
        return helper.peek();
    }
}

不同步輔助棧

輔助棧和數據棧維持相同大小--空間開銷
如何減少空間開銷???
可以重減少輔助棧中重複值入手:
例:
插入1,2,3,輔助棧中存放的全部是1,造成了空間浪費:

現在考慮插入時,輔助棧只存放小於當前最小值的。
輔助棧的出棧怎麼辦?
舉例:
1 1
2 0
1
0
3
只有當兩個棧棧頂相同的時候輔助棧纔出棧,數據棧3出棧時輔助棧0不出棧,0出棧時它纔出棧
問題來了:數據棧1出棧時把輔助棧的1帶出棧了,造成不匹配。
原因就是插入時的重複值問題,入棧時和最小值相同才行,才能在出棧時不被破壞。

於是改變原來的策略:當前元素<=最小值時輔助棧插入,只有大於時不插入。
上面的例子:
1 1
2 1
1 0
0
3
操作:
數據棧3出棧,輔助棧不出棧,最小值還是0
數據棧0出棧,輔助棧0也出棧,最小值是1
數據棧1出棧,輔助棧1出棧,最小值是1
數據棧2出棧,輔助棧1不出棧,最小值是1
數據棧1出棧,輔助棧1也出棧,兩個棧皆空
可見算法是可以工作的。

減少了空間,必然由於各種判斷增加時間

class MinStack{
    private Stack<Integer> stack;
    private Stack<Integer> helper;
    public MinStack() {
        stack = new Stack<>();
        helper = new Stack<>();
    }

    public void push(int x) {
        stack.push(x);
        if (helper.isEmpty())helper.push(x);
        else if(x<=helper.peek()){
            helper.push(x);
        }
    }

    public void pop() {
        int tmp= stack.pop();
        if (helper.peek()==tmp) helper.pop();
    }

    public int top() {
        return stack.peek();
    }
    public int getMin() {
        return helper.peek();
    }
}

不用輔助棧

上面的輔助棧不過是通過是數據棧元素的一個映射

  • 同步的是一對一映射
  • 不同步的是一對多映射
    那不用輔助棧也行,直接定義類Ele<元素,最小值>,把Ele當做數據棧的元素不就好了!

更直接地,不要其他數據複合數據類型也行,題目中使用的是Integer數據類型,那我使用Long類型的棧Stack,把元素值放到Long的高32位,最小值放到低32位,實現稍微麻煩一點而已。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章