Min Stack
Every entry on the stack is a pair (value, minSoFar), where minSoFar is the smallest value from the bottom of the stack up to and including this entry. push computes it from the entry below. getMin just reads the top entry's minSoFar. pop needs no extra work.
Every entry's minSoFar is the smallest value from the bottom of the stack up to that entry. Because entries below the top never change, this stays true for as long as the entry is on the stack.
Problem
Build a class MinStack: a normal stack that can also tell you its smallest value at any moment.
MinStack()creates an empty stack.void push(int val)putsvalon top.void pop()removes the top value.int top()returns the top value.int getMin()returns the smallest value currently on the stack.
Every one of these must run in O(1) time.
A sequence of calls to push, pop, top and getMin.
The return value of each top and getMin call. push and pop return nothing.
With -2, 0, -3 on the stack the smallest is -3. After popping -3 the top is 0, and the smallest of what is left (-2, 0) is -2.
- β’ β2^31 β€ val β€ 2^31 β 1
- β’ pop, top and getMin are only called when the stack is not empty
- β’ At most 3 Β· 10^4 calls in total
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck β each hint is counted.
- 1.
If I keep one variable
minVal, what goes wrong when the current minimum is popped? - 2.
When a value is pushed, which values can it be compared with? Which values are below it, and do they ever change while it is on the stack?
- 3.
For a given entry, is "the smallest value from the bottom up to here" fixed, or can later pushes and pops change it?
- 4.
What happens if the same minimum value is pushed twice and then popped once?
- 5.
Which is the trade-off: extra memory for every entry, or extra memory only for some entries?
Brute force approach
Better approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | Plain vector stack; getMin scans every value | O(N) | O(N) |
| Better | Main stack + a stack of mins pushed only when val <= current min | O(1) | O(N) |
| Optimal | Each entry stores its value and the min of everything up to it | O(1) | O(N) |
Why does this belong to this pattern?
- βpush / pop / topβLast in, first out: changes only ever happen at the top.
- βgetMin in O(1)βWe cannot scan, so the answer must be stored somewhere and ready to read.
- βafter a pop, the min may go back to an older valueβOld answers must be remembered in the same last-in, first-out order β store them in the stack itself.
This is the anchor for the sub-pattern: the stack is not used to match or cancel anything, it is the thing being simulated, and each entry carries extra info computed from the entry below. Simplify Path and Asteroid Collision also simulate a process with a stack, but there new items actively remove old ones (.. pops a folder, a left-mover destroys right-movers). Here pops only come from the caller.
Don't make this mistake
Pattern-confusion trap: this is not "running minimum of an array". An array only grows, but a stack also shrinks. When the current min is popped, one variable cannot tell you what the min was before it was pushed. You need to remember the min at every height.
Push 3, then 3 again. With < only one 3 is in mins. Pop the second 3: it equals mins.top(), so mins is popped, and getMin now returns something bigger than 3 even though a 3 is still on the stack.
If the popped value was the current min, mins still reports it, so getMin returns a value that is no longer on the stack. Check before popping st, while you can still read the value.
st.top().first is just the last value pushed, not the smallest. Push 1, 5, 3: with .first the entry for 3 would store min(3, 5) = 3, but the real min is 1.
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Stack translate into production architectures and low-level memory mechanics.