微信公众号:路人zhang
扫码关注微信公众号

回复“面试手册”,获取本站PDF版

回复“简历”,获取高质量简历模板

回复“加群”,加入程序员交流群

回复“电子书”,获取程序员类电子书

当前位置: 算法 > 剑指offer > 剑指offer 30.包含min函数的栈

题目描述

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

示例:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.min();   --> 返回 -2.

提示:

  1. 各函数的调用总次数不超过 20000 次


题解

(单调栈) O(1)

用一个栈 stk 维护基本的栈操作,同时需要维护一个单调栈 min_stk,用来返回栈中的最小值

  1. push(x): 压入 x 到基本栈 stk,同时判断单调栈 min_stk 是否为空或当前元素 x 是否小于等于当前栈顶元素,如果是,同样将 x 压入到单调栈中

这里为什么相等也要入栈,是因为在 pop 的时候我们判断的条件就是如果两个栈顶相等,min_stk 也要弹出元素,所以 min_stk 中要压入 x,否则如果 stk 的最小值为有多个相等的值 x,那么 stk 和 min_stk 都弹出 x 之后,此时 stk 的最小值仍然是 x,但 min_stk 的栈顶一定小于 x,与答案不符,所以必须要压入 x

  1. pop(): 在基本栈 stk 弹出之前,需要判断 stk 的栈顶和 min_stk 的栈顶是否相等,如果相等 min_stk 也要弹出栈顶
  2. top(): stk.top()
  3. getMin(): min_stk.top()

时间复杂度

四个操作都只有常数次入栈出栈操作,所以时间复杂度是 O(1)

空间复杂度

O(n)

C++ 代码

class MinStack {
public:
    stack<int> stk, min_stk;

    /** initialize your data structure here. */
    MinStack() {

    }
    
    void push(int x) {
        stk.push(x);
        if (min_stk.empty() || min_stk.top() >= x) min_stk.push(x);
    }
    
    void pop() {
        int t = stk.top();
        stk.pop();
        if (t == min_stk.top()) min_stk.pop();
    }
    
    int top() {
        return stk.top();
    }
    
    int min() {
        return min_stk.top();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->min();
 */

Java 代码

class MinStack {
    Stack<Integer> stack;
    Stack<Integer> min_stk;

    /** initialize your data structure here. */
    public MinStack() {
        stack = new Stack<>();
        min_stk = new Stack<>();
    }
    
    public void push(int x) {
        stack.push(x);
        if (min_stk.isEmpty() || min_stk.peek() >= x)
            min_stk.push(x);
    }
    
    public void pop() {
        int x = stack.pop();
        if (x == min_stk.peek())
            min_stk.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int min() {
        return min_stk.peek();
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(x);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.min();
 */

Python 代码

class MinStack:

    def __init__(self):
        self.stack = []
        self.min_stk = []

    def push(self, x: int) -> None:
        self.stack.append(x)
        if not self.min_stk or self.min_stk[-1] >= x:
            self.min_stk.append(x)

    def pop(self) -> None:
        x = self.stack.pop()
        if x == self.min_stk[-1]:
            self.min_stk.pop()

    def top(self) -> int:
        return self.stack[-1]

    def min(self) -> int:
        return self.min_stk[-1]


# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.min()

本文由读者提供Github地址:https://github.com/tonngw


点击面试手册,获取本站面试手册PDF完整版