5、最小栈

厨子大约 3 分钟数据结构算法算法基地面试刷题

题目描述

最小栈open in new window

设计一个支持 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,top 等操作,并且能够返回栈的最小值。比如此时栈中的元素为 5,1,2,3。我们执行 getMin() ,则能够返回 1。这块是这个题目的精髓所在,见下图。

单调栈
单调栈

我们一起先通过一个视频先看一下具体解题思路,通过视频一定可以整懂的,我们注意观察栈 B 内的元素。

我们来对视频进行解析 1.我们执行入栈操作时,先观察需要入栈的元素是否小于栈 B 的栈顶元素,如果小于则两个栈都执行入栈操作。

2.栈 B 的栈顶元素则是栈 A 此时的最小值。则 getMin() 只需返回栈 B 的栈顶元素即可。

3.出栈时,需要进行对比,若栈 A 和栈 B 栈顶元素相同,则同时出栈,出栈好 B 的栈顶保存的仍为此时栈 A 的最小元素

题目代码

class MinStack {
    //初始化
    Stack<Integer> A,B;
    public MinStack() {
          A = new Stack<>();
          B = new Stack<>();
    }
    //入栈,如果插入值,当前插入值小于栈顶元素,则入栈,栈顶元素保存的则为当前栈的最小元素
    public void push(int x) {
        A.push(x);
        if (B.isEmpty() || B.peek() >= x) {
            B.push(x);
        }

    }
    //出栈,如果A出栈等于B栈顶元素,则说明此时栈内的最小元素改变了。
    //这里需要使用 equals() 代替 == 因为 Stack 中存储的是 int 的包装类 Integer
    public void pop() {
        if (A.pop().equals(B.peek()) ) {
            B.pop();
        }
    }
    //A栈的栈顶元素
    public int top() {
        return A.peek();
    }
    //B栈的栈顶元素
    public int getMin() {
        return B.peek();
    }
}

GO Code:

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

/** initialize your data structure here. */
func Constructor() MinStack {
    return MinStack{
        stack:  []int{},
        minStk: []int{},
    }
}

// Push 入栈,如果插入值,当前插入值小于栈顶元素,则入栈,栈顶元素保存的则为当前栈的最小元素
func (m *MinStack) Push(x int)  {
    m.stack = append(m.stack, x)
    if len(m.minStk) == 0 || m.minStk[len(m.minStk) - 1] >= x {
        m.minStk = append(m.minStk, x)
    }
}

// Pop 出栈,如果stack出栈等于minStk栈顶元素,则说明此时栈内的最小元素改变了。
func (m *MinStack) Pop()  {
    temp := m.stack[len(m.stack) - 1]
    m.stack = m.stack[: len(m.stack) - 1]
    if temp == m.minStk[len(m.minStk) - 1] {
        m.minStk = m.minStk[: len(m.minStk) - 1]
    }
}

// Top stack的栈顶元素
func (m *MinStack) Top() int {
    return  m.stack[len(m.stack) - 1]
}

// GetMin minStk的栈顶元素
func (m *MinStack) GetMin() int {
    return  m.minStk[len(m.minStk) - 1]
}