最小栈

// 最小栈
// 测试链接 : 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)(固定大小)
简洁性 ⭐⭐⭐⭐ ⭐⭐⭐
性能 ⭐⭐⭐ ⭐⭐⭐⭐⭐
可扩展性 ⭐⭐⭐⭐
实战推荐 刷题可用 面试更佳(手写)

🌟 思维延伸

如果你希望再进阶一点,可以尝试以下变种题:

  1. 设计一个支持获取最小值/最大值的队列

  2. 在 O(1) 空间下实现 MinStack(不允许用额外空间,只允许修改栈结构)

  3. MinStack 的优化版本,只存最小值变化时再 push(节省空间)


🧪 LeetCode 对应题目

  • LeetCode 155:Min Stack

  • 类似题:LC 716、LC 225、LC 232 等涉及栈的经典模拟题


posted @ 2025-07-17 20:02  ji415  阅读(22)  评论(0)    收藏  举报