C++怎么实现最小栈_C++O(1)获取栈最小值【数据】

1次阅读

单用一个无法o(1)获取最小值,因其仅支持栈顶操作,而最小值可能位于任意位置;需用辅助栈同步记录“截至当前的最小值”,push时x≤minstack.top()才入栈,pop时主栈弹出值等于minstack栈顶则同步弹出。

C++怎么实现最小栈_C++O(1)获取栈最小值【数据】

为什么单用一个没法 O(1) 拿到最小值

因为栈只允许在栈顶增删,而最小值可能藏在任意一层。如果每次 getMin() 都遍历一遍,就是 O(n),不满足题干要求。

核心思路是:用空间换时间,额外维护一个“同步栈”,它和主栈一起压入/弹出,但只存“到当前位置为止的最小值”。

  • 主栈进 5,当前全局最小是 5 → 辅助栈也进 5
  • 主栈再进 3,比辅助栈顶 5 小 → 辅助栈进 3
  • 主栈再进 4,不比辅助栈顶 3 小 → 辅助栈不动(或进 3,两种实现都行)
  • getMin() 直接返回辅助栈顶,O(1)

push() 时辅助栈怎么更新才不出错

关键在判断逻辑:辅助栈只在新元素 ≤ 当前最小值时才压入。用 而不是 <code>,否则重复最小值会被漏掉,导致 <code>pop()getMin() 返回错误值。

比如连续压入 3, 1, 1, 4,如果辅助栈只在 时进栈,第二个 <code>1 就不会进,等第一个 1 弹出后,辅助栈空了,但实际最小值还是 1

立即学习C++免费学习笔记(深入)”;

实操建议:

  • 初始化两个空 std::stack<int></int>:主栈 mainStack 和辅助栈 minStack
  • push(x) 时:先压 mainStack,再判断 minStack.empty() || x ,成立则压 <code>minStack
  • 别忘了处理空栈边界——getMin() 前必须检查 minStack.empty(),否则 .top() 未定义行为

pop() 时辅助栈要不要跟着弹

要,而且必须严格同步:只要 mainStack 弹出的值等于 minStack.top()minStack 就必须跟着弹一个。

不能只看“是不是当前最小”,而要看“它是不是当时被记下来的那个最小”。否则会残留过期最小值。

常见错误现象:push(2), push(1), push(1), pop(), getMin() 返回 1 是对的;但如果 pop() 时没检查相等就跳过辅助栈,第二次 getMin() 可能仍返回 1(其实是错的,应仍为 1?等等——这里恰恰说明:重复值必须都记,也必须都弹)

所以正确逻辑是:

  • pop() 先取 mainStack.top(),然后 mainStack.pop()
  • 再比较这个值是否等于 minStack.top(),相等则 minStack.pop()
  • 不相等就不管辅助栈

c++ 实现里最容易崩的三个点

不是算法难,是 C++ 栈操作细节容易踩雷:

  • std::stack::top() 对空栈调用是未定义行为,不是抛异常——程序可能当场崩溃或静默错乱,务必每次调用前用 .empty() 检查
  • 不要用 std::stack 的底层容器(如 std::vector)直接访问,它没暴露 operator[] 或迭代器;想调试时看内容,得临时转成 vector 或用 while (!s.empty()) { auto t = s.top(); s.pop(); ... }
  • 如果题目要求支持 getMin() 在空栈时返回特殊值(如 INT_MAX),别直接 return,先判空;否则线上环境可能触发 sanitizer 报告

复杂点不在结构,而在每一步的边界守卫。少一个 empty() 检查,就可能让整个类在特定输入下失效。

text=ZqhQzanResources