You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

常数时间获取栈最小元素:请解析MinStack2的push方法代码逻辑

理解MinStack2的运行逻辑

咱们来一步步拆解这个MinStack2类的设计思路和代码逻辑——它的核心目标是在常数时间O(1)内获取栈中的最小元素,用到了双栈的设计思路,其中一个栈存所有元素,另一个栈存「最小值+出现次数」的配对,避免频繁调整最小值。

初始化方法 __init__

  • 这里初始化了两个空列表:
    • self.stack:用来存储所有入栈的元素,就是普通的栈结构,负责正常的push/pop操作。
    • self.minStack:这个是关键,它里面的每个元素都是一个长度为2的列表[最小值, 出现次数],用来跟踪当前栈中的最小值以及这个最小值出现的次数。

push方法的详细逻辑

push方法负责把元素x压入栈,同时维护minStack的状态,保证它始终能正确反映当前栈的最小值:

  1. 第一步先把x压入主栈:self.stack.append(x),这是普通栈的入栈操作。
  2. 接下来判断minStack是否为空:
    • 如果minStack不为空,分三种情况处理:
      • 当x < self.minStack[-1][0]:说明x是当前栈的新最小值,直接把[x, 1]压入minStack,计数初始化为1。
      • 当x == self.minStack[-1][0]:说明当前最小值又出现了一次,不需要压入新元素,只需要把minStack栈顶元素的计数加1(self.minStack[-1][1] += 1)。
      • 当x > self.minStack[-1][0]:这里要注意,你给出的代码里会把[x, 1]压入minStack,但其实这是个冗余操作——因为x比当前最小值大,它永远不会成为当前栈的最小值,正常优化的话这里不需要做任何操作。不过咱们按给定代码的逻辑来,此时会把[x, 1]加入minStack。
    • 如果minStack为空(也就是第一次入栈):直接把[x, 1]压入minStack即可,因为第一个元素就是当前最小值。

举个实际例子

假设我们依次执行push(3)、push(2)、push(2)、push(4):

  • push(3):主栈变成[3],minStack为空,压入[3,1] → minStack = [[3,1]]
  • push(2):2 < 3,压入[2,1] → minStack = [[3,1], [2,1]]
  • push(2):等于栈顶的2,计数加1 → minStack = [[3,1], [2,2]]
  • push(4):4 > 2,按代码逻辑压入[4,1] → minStack = [[3,1], [2,2], [4,1]]

为什么要存计数?

这个设计的妙处在于处理pop操作时(虽然你没给出pop代码,但逻辑是通的):如果弹出的元素是当前最小值,只需要把minStack栈顶的计数减1;如果计数减到0,再弹出minStack的栈顶元素。这样就能保证minStack的栈顶始终是当前栈的最小值,而且所有操作都是O(1)时间,不会因为频繁弹出最小值而需要遍历栈找新的最小值。

内容的提问来源于stack exchange,提问作者John Asare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:14:55