LeetCode 155:最小栈设计精解

LeetCode155

设计一个支持 pushpoptop 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

MinStack() 初始化堆栈对象。

void push(int value) 将元素 value 推入堆栈。

void pop() 删除堆栈顶部的元素。

int top() 获取堆栈顶部的元素。

int getMin() 获取堆栈中的最小元素。

示例 1:

输入:

"MinStack","push","push","push","getMin","pop","top","getMin"

\[\],\[-2\],\[0\],\[-3\],\[\],\[\],\[\],\[\]

输出:

null,null,null,null,-3,null,0,-2

解释:

MinStack minStack = new MinStack();

minStack.push(-2);

minStack.push(0);

minStack.push(-3);

minStack.getMin(); --> 返回 -3.

minStack.pop();

minStack.top(); --> 返回 0.

minStack.getMin(); --> 返回 -2.

Python解法

代码示例(辅助栈)

python 复制代码
class MinStack:
    def __init__(self):
        self.stack = []
        self.min_stack = [math.inf]

    def push(self, value: int) -> None:
        self.stack.append(value)
        self.min_stack.append(min(value, self.min_stack[-1]))

    def pop(self) -> None:
        self.stack.pop()
        self.min_stack.pop()

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

    def getMin(self) -> int:
        return self.min_stack[-1]

代码示例(单栈存差值)

python 复制代码
class MinStack:
    def __init__(self):
        self.stack = []
        self.min_val = 0

    def push(self, value: int) -> None:
        if not self.stack:
            self.stack.append(0)
            self.min_val = value
        else:
            diff = value - self.min_val
            self.stack.append(diff)
            # 更小值出现,更新最小值
            if value < self.min_val:
                self.min_val = value
    def pop(self) -> None:
        diff = self.stack.pop()
        # 差值为负:说明弹出的是曾经的最小值,要还原旧最小值
        if diff < 0:
            self.min_val = self.min_val - diff

    def top(self) -> int:
        diff = self.stack[-1]
        if diff >= 0:
            return self.min_val + diff
        else:
            return self.min_val

    def getMin(self) -> int:
        return self.min_val

过程演示

Java解法

代码示例(两种)

java 复制代码
方法一:辅助栈

class MinStack {
    Deque<Integer> xStack;
    Deque<Integer> minStack;
    public MinStack() {
        xStack = new LinkedList<Integer>();
        minStack = new LinkedList<Integer>();
        minStack.push(Integer.MAX_VALUE);
    }
    
    public void push(int value) {
        xStack.push(value);
        minStack.push(Math.min(minStack.peek(), value));
    }
    
    public void pop() {
        xStack.pop();
        minStack.pop();
    }
    
    public int top() {
        return xStack.peek();
    }
    
    public int getMin() {
        return minStack.peek();
    }
}


方法二:单栈存差值


class MinStack {
    private Stack<Long> stack;
    private long minVal;

    public MinStack() {
        stack = new Stack<>();
    }

    public void push(int value) {
        if (stack.isEmpty()) {
            stack.push(0L);
            minVal = value;
        } else {
            long diff = (long) value - minVal;
            stack.push(diff);
            if (value < minVal) {
                minVal = value;
            }
        }
    }

    public void pop() {
        long diff = stack.pop();
        if (diff < 0) {
            minVal = minVal - diff;
        }
    }

    public int top() {
        long diff = stack.peek();
        if (diff >= 0) {
            return (int) (minVal + diff);
        } else {
            return (int) minVal;
        }
    }

    public int getMin() {
        return (int) minVal;
    }
}

C++解法

代码示例(两种)

cpp 复制代码
方法一:辅助栈

class MinStack {
    stack<int> x_stack;
    stack<int> min_stack;
public:
    MinStack() {
        min_stack.push(INT_MAX);
    }
    
    void push(int value) {
        x_stack.push(value);
        min_stack.push(min(min_stack.top(), value));
    }
    
    void pop() {
        x_stack.pop();
        min_stack.pop();
    }
    
    int top() {
        return x_stack.top();
    }
    
    int getMin() {
        return min_stack.top();
    }
};

方法二:单栈存差值

class MinStack {
private:
    stack<long long> st;
    long long min_val;
public:
    MinStack() {}

    void push(int value) {
        if (st.empty()) {
            st.push(0);
            min_val = value;
        } else {
            long long diff = (long long)value - min_val;
            st.push(diff);
            if (value < min_val) {
                min_val = value;
            }
        }
    }

    void pop() {
        long long diff = st.top();
        st.pop();
        if (diff < 0) {
            min_val = min_val - diff;
        }
    }

    int top() {
        long long diff = st.top();
        if (diff >= 0) {
            return min_val + diff;
        } else {
            return min_val;
        }
    }

    int getMin() {
        return min_val;
    }
};