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();
 */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章