InterviewPrepKit

Home / Coding / Stack

Min Stack

medium Original ↗
Solving tips
  • Key insight: after a pop the minimum reverts to what it was before that element arrived, so store the running min alongside each element rather than recomputing it.
  • Simplest O(1) design: push (val, min(val, prev_min)) pairs so getMin just reads the top pair's second field.
  • Two-stack optimization keeps a side stack of record minima; push on val <= mins[-1] and pop only when the departing value == mins[-1] (the <=/== pairing is what handles duplicate minima).
  • All four operations are O(1) with O(n) space; avoid a single 'current min' variable, which forces an O(n) rescan when the min is popped.

Problem

Design a stack that, in addition to the usual operations, can report its minimum element at any time. Implement a class MinStack with:

  • push(val) — put val on top of the stack
  • pop() — remove the top element
  • top() — return the top element without removing it
  • getMin() — return the smallest element currently in the stack

Every operation, including getMin, must run in O(1) time. pop, top, and getMin are only ever called on a non-empty stack.

Examples

  • push(-2), push(0), push(-3)getMin() = -3; then pop()top() = 0, getMin() = -2 — the minimum “rewinds” when the element that held it is popped.
  • push(5), push(7)getMin() = 5; pop()getMin() = 5 — popping a non-minimum leaves the minimum untouched.
  • push(1), push(1), pop()getMin() = 1 — duplicate minima: removing one copy must not lose the other.

Constraints

  • -2^31 <= val <= 2^31 - 1
  • Up to 3 * 10^4 operations total

The operation count is small, but the O(1)-per-operation requirement is the real constraint — a getMin that scans the stack is O(n) and misses the point of the problem.

Think about it first

Hint 1 A single "current minimum" variable breaks the moment you pop the minimum — what was the minimum *before* it? You'd have to rescan. What if you never threw that older information away?
Hint 2 The minimum of the stack only changes at pushes and pops — and after popping, it returns to exactly what it was before the popped element arrived. History that unwinds in LIFO order can be stored in... another stack.
Hint 3 Alongside each element (or in a parallel stack), record the minimum of everything at or below it. `getMin` reads the top of that record; `pop` discards it in lockstep. Both are O(1).
Your workspace Not runnable by design — this is your interview scratchpad. Saved on this device.