20. Min Stack
easyAsked at SnowflakeDesign a stack that supports push, pop, top, and getMin in O(1) time. Snowflake asks this to test whether you can co-locate state with operations — the same design principle behind their per-column aggregate accumulators.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Snowflake loops.
- Glassdoor (2026-Q1)— Snowflake execution-engine team uses this as design warm-up.
- LeetCode Discuss (2025-12)— Recurring at Snowflake new-grad onsites.
Problem
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. Implement the MinStack class: MinStack() initializes the stack object. void push(int val) pushes the element val onto the stack. void pop() removes the element on the top of the stack. int top() gets the top element of the stack. int getMin() retrieves the minimum element in the stack.
Constraints
-2^31 <= val <= 2^31 - 1Methods pop, top and getMin operations will always be called on non-empty stacks.At most 3 * 10^4 calls will be made to push, pop, top, and getMin.
Examples
Example 1
MinStack().push(-2); push(0); push(-3); getMin(); pop(); top(); getMin();-3, _, 0, -2Approaches
1. Scan for min on demand
Single stack. getMin walks the whole stack.
- Time
- O(1) push/pop, O(n) getMin
- Space
- O(n)
class MinStack {
constructor() { this.s = []; }
push(v) { this.s.push(v); }
pop() { this.s.pop(); }
top() { return this.s[this.s.length - 1]; }
getMin() { return Math.min(...this.s); }
}Tradeoff: Violates the O(1) getMin requirement.
2. Two stacks (optimal)
Main stack of values. Auxiliary stack of running min. Push to aux only when new value <= current min. Pop from aux when popped value equals current min.
- Time
- O(1) all ops
- Space
- O(n)
class MinStack {
constructor() {
this.stack = [];
this.mins = [];
}
push(v) {
this.stack.push(v);
if (this.mins.length === 0 || v <= this.mins[this.mins.length - 1]) {
this.mins.push(v);
}
}
pop() {
const v = this.stack.pop();
if (v === this.mins[this.mins.length - 1]) this.mins.pop();
}
top() { return this.stack[this.stack.length - 1]; }
getMin() { return this.mins[this.mins.length - 1]; }
}Tradeoff: All ops O(1). Auxiliary stack only stores new minima, so it's at most n entries (typically far fewer).
Snowflake-specific tips
Snowflake interviewers want the two-stack version and a discussion of the <= edge case (must use <=, not <, for duplicate minima). Bonus signal: pivot to constant-time aggregate maintenance — Snowflake's incremental materialized views use similar co-located state to keep min/max current as rows are inserted.
Common mistakes
- Using < instead of <= when pushing to the aux stack — fails when the min appears multiple times.
- Storing only one running min variable — fails on pop because you lose history.
- Forgetting to pop from aux when the popped value was the current min.
Follow-up questions
An interviewer at Snowflake may pivot to one of these next:
- Implement using a single stack of (value, currentMin) pairs.
- Min Queue (FIFO equivalent).
- How does Snowflake maintain incremental min/max in materialized views?
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why <= and not <?
If you have duplicate minimum values [2, 1, 1] and you pop a 1, the next getMin should still return 1. Using <= ensures the aux stack has multiple copies of 1, one popped per pop.
How does this map to Snowflake?
Incremental materialized view refresh keeps per-aggregate state with the rows that produced it. Maintaining a running min is the simplest example of this pattern; the full implementation generalizes to deltas + retracts.
Practice these live with InterviewChamp.AI
Drill Min Stack and other Snowflake interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →