21. Min Stack
easyAsked at DatadogDesign a stack that supports push, pop, top, and getMin all in O(1). Datadog asks this because it's the same shape as a streaming min-aggregate that needs to handle rollbacks (transactional ingestion).
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Datadog loops.
- Glassdoor (2026-Q1)— Datadog onsite design-warmup — graded on the parallel-stack insight.
- Blind (2025-11)— Recurring at Datadog onsites.
Problem
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. Implement the MinStack class with push(val), pop(), top(), and getMin() — all O(1).
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.
Examples
Example 1
MinStack(), push(-2), push(0), push(-3), getMin(), pop(), top(), getMin()[null,null,null,null,-3,null,0,-2]Approaches
1. Recompute min on every getMin
Single stack; scan on every getMin call.
- Time
- getMin O(n), others O(1)
- 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: getMin is O(n). Datadog will fail this for missing the constant-time requirement.
2. Parallel min stack (optimal)
Maintain a second stack of running minima. On push, push min(val, currentMin). On pop, pop both.
- Time
- O(1) all ops
- Space
- O(n)
class MinStack {
constructor() {
this.s = [];
this.mins = [];
}
push(v) {
this.s.push(v);
if (this.mins.length === 0 || v <= this.mins[this.mins.length - 1]) {
this.mins.push(v);
} else {
this.mins.push(this.mins[this.mins.length - 1]);
}
}
pop() {
this.s.pop();
this.mins.pop();
}
top() { return this.s[this.s.length - 1]; }
getMin() { return this.mins[this.mins.length - 1]; }
}Tradeoff: All ops O(1). The parallel-stack pattern is exactly what Datadog uses for rollback-able running aggregates.
Datadog-specific tips
Datadog cares whether you can articulate the invariant: 'mins[i] = the minimum of stack[0..i].' Variants they ask: 'reduce memory by only pushing onto mins when val <= current min' — works, but pop logic gets trickier (only pop mins when val === current min).
Common mistakes
- Using Math.min(...this.s) — looks like O(1) but is O(n) per call. Hidden bug.
- Only pushing onto mins when val < currentMin (strict) — breaks on equal values during pop.
- Forgetting to push to BOTH stacks symmetrically — desyncs and corrupts state.
Follow-up questions
An interviewer at Datadog may pivot to one of these next:
- Min Queue — same idea but FIFO; needs two deques.
- Max Stack (LC 716) — symmetric problem.
- Datadog-style: rollback-able streaming min over a transactional ingest log.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Can you save memory by not pushing every time?
Yes — only push to mins when val <= current min. But then pop logic must check whether the val being popped equals the top of mins, and pop mins only when so.
Why two stacks instead of one with pairs?
Equivalent memory; two stacks are cleaner because pop on each is independent and you avoid object allocation per push.
Practice these live with InterviewChamp.AI
Drill Min Stack and other Datadog interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →