Skip to content
mlmentorship

Min Stack

Build a stack that returns its current minimum in constant time.

Published · 4 min read ·Core ·Foundation

30-second answer map

Visual first · depth when needed

Store each value with the minimum for its entire stack prefix, so the top pair always answers get_min().

Preparing the visual…

ML breadth · active recall

Practice before you read

8 minutes. Explain the mechanism, why it works, when it fails, and one alternative.

How practice works

ML breadth · closed-book attempt

Min Stack

Explain the mechanism, why it works, when it fails, and one alternative.

08:00recommended time

Closing or reloading clears the scratchpad. Only score, weak rubric dimensions, attempt count, and retry date can be stored locally.

Build a stack that returns its current minimum in constant time.

Start with the concrete trace below. It shows the state the algorithm must carry as it runs.

Problem trace

Min Stack: Store each value with the minimum for its entire stack prefix, so the top pair always answers get_min().

Input and goalBuild a stack that returns its current minimum in constant time.
Initialize an empty MinStackBefore any operation, the pair stack is empty.
emptytopempty
columnsvalue | minimum so farlayoutbottom to topoperationspush(5), push(2), push(4), get_min(), pop(), get_min(), top()actioninitialize

Recognize it
Use this pattern when ordinary stack operations must also answer an aggregate such as the current minimum in constant time, including immediately after pops.
Keep true
For every stored pair (value, minimum), minimum equals the smallest value from the bottom through that pair; therefore the top pair summarizes the complete current stack.
Reuse it
Attach any reversible prefix summary needed later to each stack item; the same technique supports max stacks, depth summaries, and constant-time aggregate reads after rollback.
Read it this way: Before any operation, the pair stack is empty. Step through the frames to watch the state change. The last frame shows the answer or the stopping condition.

Pattern: Store the answer needed later with each item.

Simple idea: Save (value, minimum so far) for every pushed value. When an item is removed, the earlier minimum is already stored under it.

class MinStack:
   def __init__(self) -> None:
      self.stack: list[tuple[int, int]] = []

   def push(self, value: int) -> None:
      minimum = min(value, self.stack[-1][1]) if self.stack else value
      self.stack.append((value, minimum))

   def pop(self) -> None:
      self.stack.pop()

   def top(self) -> int:
      return self.stack[-1][0]

   def get_min(self) -> int:
      return self.stack[-1][1]

Cost: time per operation and space.