最小栈
// 最小栈
// 测试链接 : https://leetcode.cn/problems/min-stack/
public class GetMinStack {
// 提交时把类名、构造方法改成MinStack
class MinStack1 {
public Stack<Integer> data;
public Stack<Integer> min;
public MinStack1() {
data = new Stack<Integer>();
min = new Stack<Integer>();
}
public void push(int val) {
data.push(val);
if (min.isEmpty() || val <= min.peek()) {
min.push(val);
} else { // !min.isEmpty() && val > min.peek()
min.push(min.peek());
}
}
public void pop() {
data.pop();
min.pop();
}
public int top() {
return data.peek();
}
public int getMin() {
return min.peek();
}
}
// 提交时把类名、构造方法改成MinStack
class MinStack2 {
// leetcode的数据在测试时,同时在栈里的数据不超过这个值
// 这是几次提交实验出来的,哈哈
// 如果leetcode补测试数据了,超过这个量导致出错,就调大
public final int MAXN = 8001;
public int[] data;
public int[] min;
int size;
public MinStack2() {
data = new int[MAXN];
min = new int[MAXN];
size = 0;
}
public void push(int val) {
data[size] = val;
if (size == 0 || val <= min[size - 1]) {
min[size] = val;
} else {
min[size] = min[size - 1];
}
size++;
}
public void pop() {
size--;
}
public int top() {
return data[size - 1];
}
public int getMin() {
return min[size - 1];
}
}
}
这段代码实现了两个版本的 最小栈(Min Stack),分别基于:
Stack<Integer>标准库:MinStack1- 数组模拟栈:
MinStack2
🚀 一、最小栈核心思想
目标:
在常数时间 O(1) 内实现:
-
push(x):压入栈 -
pop():弹出栈 -
top():获取栈顶 -
getMin():获取当前栈内最小值
🧩 二、MinStack1 — 利用双栈实现
Stack<Integer> data; // 正常数据栈
Stack<Integer> min; // 同步最小值栈
每当压入一个元素 val:
-
data.push(val)正常入栈 -
min.push(当前最小值):-
如果是更小值:直接压入
-
否则重复前一个
min.peek(),确保同步
-
✅ 特点
-
时间复杂度: 全部操作 O(1)
-
空间复杂度: 每个元素都在
min中保留一份,占用 2N
💡 示例:
入栈序列:[3, 5, 2, 1]
| 操作 | data 栈 | min 栈 |
|---|---|---|
| push(3) | 3 | 3 |
| push(5) | 3 5 | 3 3 |
| push(2) | 3 5 2 | 3 3 2 |
| push(1) | 3 5 2 1 | 3 3 2 1 |
pop() 后两个栈同时弹出,min 始终保持同步。
🧠 三、MinStack2 — 数组实现(高性能版本)
int[] data = new int[MAXN];
int[] min = new int[MAXN];
int size;
✅ 优点
-
所有操作仍然是 O(1)
-
避免了栈对象创建(比
new Stack<>更节省 GC 和对象开销) -
适合性能敏感场景,例如 LeetCode 提交刷题
⚠️ 注意
-
MAXN = 8001是根据实测数据设定的,不可泛用。 -
如果栈中元素数超过
MAXN,你需要手动扩容或者使用动态结构(如ArrayList或手动扩展数组)。
✅ 对比总结
| 特性 | MinStack1(双栈) | MinStack2(数组) |
|---|---|---|
| 时间复杂度 | O(1) | O(1) |
| 空间复杂度 | O(n) | O(n)(固定大小) |
| 简洁性 | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 性能 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 可扩展性 | ⭐⭐⭐⭐ | ⭐ |
| 实战推荐 | 刷题可用 | 面试更佳(手写) |
🌟 思维延伸
如果你希望再进阶一点,可以尝试以下变种题:
-
设计一个支持获取最小值/最大值的队列
-
在 O(1) 空间下实现 MinStack(不允许用额外空间,只允许修改栈结构)
-
MinStack 的优化版本,只存最小值变化时再 push(节省空间)
🧪 LeetCode 对应题目
-
LeetCode 155:Min Stack
-
类似题:LC 716、LC 225、LC 232 等涉及栈的经典模拟题

浙公网安备 33010602011771号