leetcode 探索隊列與棧 最小棧

題目

設計一個支持 push ,pop ,top 操作,並能在常數時間內檢索到最小元素的棧。

push(x) —— 將元素 x 推入棧中。
pop() —— 刪除棧頂的元素。
top() —— 獲取棧頂元素。
getMin() —— 檢索棧中的最小元素。

示例:

輸入:
[“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”]
[[],[-2],[0],[-3],[],[],[],[]]
輸出:
[null,null,null,null,-3,null,0,-2]

分析

最小棧,如果只使用一個的話,那麼是沒法記錄最下的元素,如果在push的時候,比較記錄最小值,那也只能記錄一個最小值,但這個元素被刪除時候,就需要遍歷計算了,所以這樣的方法不可取。

**我們需要一個當刪除一個最小值時,我們還有一個次最小值,然後繼續pop元素時候,當次最小值也被pop出去的時候,我們還有一個次次最小值。**即我們希望有一個數據結構,能夠存儲類似第一最小值,第二最小值,第三最小值,,,,,,在這裏想到了棧,它還能實現O(1)返回最小值。我們用一個輔助棧,存儲這個當前的最小值,這樣每次push的時候,我們發現它比之前的最小值小,那麼就將它push到鋪助棧中,如果我們遇到比當前棧輔助棧棧頂元素大,就不需要考慮。這裏注意如果push的元素恰好等於輔助棧棧頂元素,那麼也是需要push進去的,否則pop出相同大小元素時候,會把最小棧給pop沒了。

解法

type MinStack struct {
    stack []int
    minstack []int
}

/** initialize your data structure here. */
func Constructor() MinStack {
    return MinStack{
    }
}

func (this *MinStack) Push(x int)  {
    if len(this.stack) == 0{
        this.minstack = append(this.minstack, x)
    } else {
        // 只有比輔助棧的棧頂元素小,就需要入棧,一樣大的也需要入棧,因爲出棧的時候,如果遇到一樣大的,就出了,回有兩邊不同步的問題
        minLen := len(this.minstack)
        if x <= this.minstack[minLen-1] {
            this.minstack = append(this.minstack, x)
        }
    }
    this.stack = append(this.stack, x)
    // fmt.Printf("push %d into %v \n", x, this.stack)
    // fmt.Printf("minstack: %v\n", this.minstack)
}

func (this *MinStack) Pop()  {
    length := len(this.stack)
    if length == 0 {
        return
    }
    minLen := len(this.minstack)
    if this.stack[length-1] == this.minstack[minLen-1] {
        this.minstack = this.minstack[:minLen-1]
    }
    this.stack = this.stack[:length-1]
}

func (this *MinStack) Top() int {
    length := len(this.stack)
    if length == 0 {
        return -1
    }
    return this.stack[length-1]
}

func (this *MinStack) GetMin() int {
    if len(this.stack) == 0 {
        return -1
    }
    return this.minstack[len(this.minstack)-1]
}

/**
 * Your MinStack object will be instantiated and called as such:
 * obj := Constructor();
 * obj.Push(x);
 * obj.Pop();
 * param_3 := obj.Top();
 * param_4 := obj.GetMin();
 */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章