Min Stack — Coding Interview Walkthrough
Min Stack is one of those problems where the solution is short but the reasoning matters more than the code. Interviewers aren’t checking whether you can write a stack — they’re checking whether you understand why tracking the minimum at each depth works, and whether you can articulate the LIFO insight that makes it possible.
The Problem
Design a stack that supports push, pop, top, and getMin — all in O(1) time. getMin() must return the minimum element in the stack at any time.
Example
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); // → -3
minStack.pop();
minStack.top(); // → 0
minStack.getMin(); // → -2
Already comfortable with the solution? Practice it in a mock interview →
What Interviewers Are Actually Testing
| Skill | What Interviewers Observe |
|---|---|
| Auxiliary state insight | Do you think to track the minimum alongside each element? |
| Stack LIFO reasoning | Do you understand that when you pop a min, the previous min restores? |
| O(1) constraint | Do you avoid scanning the stack to find the minimum? |
| Design clarity | Is your class interface clean and well-encapsulated? |
Step 1: Clarifying Questions
- Must all operations be O(1)? Yes — this is the core constraint.
- What if
popis called on an empty stack? Assume operations are always valid per problem constraints. - Can there be duplicate minimum values? Yes — handle this correctly or
getMinbreaks on pop.
Step 2: The Naive Idea
Use a regular stack. For getMin, scan the entire stack and return the minimum. O(n) per getMin call — violates the constraint.
Step 3: The Key Insight
Store the current minimum alongside each element. Every time you push, record what the minimum was at that moment. When you pop, the previous minimum is automatically restored because LIFO reverses the push order. No scanning required.
---
Step 4: Optimal Strategy
Use a single stack of (value, current_min) tuples — or use two parallel stacks.
Approach A — Stack of tuples:
- Push
(val, min(val, current_min)). getMin()reads the second element of the top tuple.
Approach B — Two stacks:
- Main stack holds values.
- Min stack holds the current minimum at each depth.
Python Implementation
Stack of tuples (cleaner):
class MinStack:
def __init__(self):
self.stack = [] # (value, current_min)
def push(self, val: int) -> None:
current_min = min(val, self.stack[-1][1]) if self.stack else val
self.stack.append((val, current_min))
def pop(self) -> None:
self.stack.pop()
def top(self) -> int:
return self.stack[-1][0]
def getMin(self) -> int:
return self.stack[-1][1]
Two parallel stacks:
class MinStack:
def __init__(self):
self.stack = []
self.min_stack = []
def push(self, val: int) -> None:
self.stack.append(val)
min_val = min(val, self.min_stack[-1]) if self.min_stack else val
self.min_stack.append(min_val)
def pop(self) -> None:
self.stack.pop()
self.min_stack.pop()
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.min_stack[-1]
Both are O(1) per operation and O(n) space total.
Time & Space Complexity
| Operation | Time | Space |
|---|---|---|
| push | O(1) | O(1) per element |
| pop | O(1) | — |
| top | O(1) | — |
| getMin | O(1) | — |
| Total space | — | O(n) |
Common Interview Mistakes
-
Storing only the global minimum. If you pop the minimum, your stored value is now wrong. You need the minimum at every stack depth.
-
Not handling the empty stack edge case in push. When the stack is empty,
current_min = val(no previous min to compare against). -
Duplicates. If
-3is pushed twice and popped once,getMinshould still return-3. Both approaches handle this correctly because they track min per push, not per unique value. -
Forgetting both stacks must pop together. In the two-stack approach, forgetting to pop
min_stackinpop()desyncs them.
What a Strong Candidate Sounds Like
“The O(1) constraint rules out scanning on getMin. The insight is that the minimum is a function of what’s currently in the stack. If I track ‘what is the minimum so far’ at each level when I push, then getMin is just reading the top of that min record. When I pop, the previous level’s minimum automatically becomes current. I’ll use a stack of (value, current_min) tuples.”
Example Interview Dialogue
Interviewer: Why does storing the minimum at each level work when you pop?
Candidate: Because of LIFO ordering. When I push, I snapshot the current minimum. When I pop that element, every element below it was pushed before it, so the minimum of those elements hasn’t changed. The snapshot from the element below is still correct.
Interviewer: Would a single variable tracking the current min work?
Candidate: No. When I pop the current minimum, I’d need to scan the entire stack to find the new minimum. That’s O(n). The per-level approach avoids this entirely because each level already knows its own minimum.
Related Problems to Practice
- Valid Parentheses — Stack fundamentals.
- Basic Calculator — Stack-based expression evaluation.
- Implement Queue using Stacks — Design with stacks.
Practice This in a Mock Interview
Min Stack is deceptively simple — the code is short, but explaining why the LIFO property makes per-level minimum tracking work is what separates strong candidates from weak ones.
Start a mock interview for Min Stack on Intervu.
Further reading:
- How to Prepare for a Coding Interview in 2026, the complete roadmap
- Why LeetCode alone isn’t enough, and what to practice instead
- Practice any LeetCode problem as a live mock interview
- The Grind 75 Pathway, a structured study plan with AI practice links
- Browse all walkthroughs on GitHub