题目
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack()初始化堆栈对象。void push(int val)将元素val推入堆栈。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.
提示:
-231 <= val <= 231 - 1pop、top和getMin操作总是在 非空栈 上调用push,pop,top, andgetMin最多被调用3 * 104次
解题思路
很简单其实,我们维护俩个栈,其中一个放入正常值,另一个在放入的时候将栈顶和这个值进行比较,放入较小的一个
代码&注释
java
package com.zxl.LeetCode.Solution;
import java.util.Deque;
import java.util.LinkedList;
/**
* 支持常数时间获取最小值的栈(Min Stack)
*
* 设计目标:
* - 实现一个栈,除了常规的 push、pop、top 操作外,
* - 还能以 O(1) 时间复杂度获取当前栈中的最小元素(getMin)。
*
* 核心思路:
* - 使用两个栈:
* 1. 主栈(stack):存储所有入栈的元素。
* 2. 辅助栈(minStack):同步记录"到当前为止"的最小值。
* - 每次 push 时,minStack 压入当前全局最小值;
* 每次 pop 时,两个栈同步弹出,保持状态一致。
*
* 时间复杂度:所有操作均为 O(1)
* 空间复杂度:O(n),n 为元素个数(辅助栈与主栈等长)
*/
public class MinStack {
// 主栈:用于存储所有入栈的整数元素
Deque<Integer> stack;
// 辅助栈:用于存储对应主栈每个状态下(从底到当前)的最小值
Deque<Integer> minStack;
/**
* 构造函数:初始化两个栈
*
* 注意:minStack 初始压入 Integer.MAX_VALUE 作为"哨兵值"(sentinel),
* 这样在第一次 push 时,Math.min(minStack.peek(), val) 能正确返回 val,
* 同时避免了空栈 peek 异常(虽然本实现中不会出现空栈 peek,但哨兵简化逻辑)。
*/
public MinStack() {
stack = new LinkedList<>(); // 初始化主栈
minStack = new LinkedList<>(); // 初始化辅助栈
minStack.push(Integer.MAX_VALUE); // 哨兵值,代表"无穷大"的初始最小值
}
/**
* 入栈操作
*
* @param val 要压入栈的整数值
*
* 步骤:
* 1. 将 val 压入主栈;
* 2. 计算当前最小值 = min(辅助栈当前栈顶, val);
* 3. 将该最小值压入辅助栈。
*
* 示例:
* 当前 minStack 栈顶为 -2,若 push(0) → 新最小值仍为 -2;
* 若 push(-3) → 新最小值为 -3。
*/
public void push(int val) {
stack.push(val); // 主栈入栈
// 辅助栈入栈:取当前最小值与新值的较小者
minStack.push(Math.min(minStack.peek(), val));
}
/**
* 出栈操作
*
* 同时从主栈和辅助栈弹出栈顶元素,
* 保证两个栈的"状态对齐"------即 minStack 的栈顶始终对应 stack 当前状态的最小值。
*/
public void pop() {
stack.pop(); // 主栈弹出
minStack.pop(); // 辅助栈同步弹出
}
/**
* 获取栈顶元素(不弹出)
*
* @return 当前栈顶的整数值
*/
public int top() {
return stack.peek(); // 直接返回主栈栈顶
}
/**
* 获取当前栈中的最小元素
*
* @return 当前栈中最小的整数值
*
* 由于 minStack 的栈顶始终维护着当前全局最小值,
* 因此直接返回 minStack.peek() 即可,时间复杂度 O(1)。
*/
public int getMin() {
return minStack.peek(); // 返回辅助栈栈顶(即当前最小值)
}
}