Min Stack
Stack with O(1) getMin — each entry carries the min of itself and everything below.
3 min read
design stack
Problem#
Design a stack supporting push, pop, top, and getMin — all in O(1).
Examples#
push(-2); push(0); push(-3); getMin()→-3.pop(); top()→0;getMin()→-2.
Constraints#
-2^31 <= val <= 2^31 - 1, up to3 * 10^4calls.
Approach#
Stack of pairs (value, currentMin). On push, the new min is min(val, prevMin). On pop, the prior min naturally restores.
Solution#
class MinStack { vector<pair<int,int>> st; // {val, minSoFar}public: void push(int val) { int m = st.empty() ? val : min(val, st.back().second); st.push_back({val, m}); } void pop() { st.pop_back(); } int top() { return st.back().first; } int getMin() { return st.back().second; }};type entry struct{ val, min int }
type MinStack struct { st []entry}
func Constructor() MinStack { return MinStack{}}
func (s *MinStack) Push(val int) { m := val if len(s.st) > 0 && s.st[len(s.st)-1].min < m { m = s.st[len(s.st)-1].min } s.st = append(s.st, entry{val, m})}
func (s *MinStack) Pop() { s.st = s.st[:len(s.st)-1]}
func (s *MinStack) Top() int { return s.st[len(s.st)-1].val}
func (s *MinStack) GetMin() int { return s.st[len(s.st)-1].min}from typing import List, Tuple
class MinStack: def __init__(self) -> None: self.st: List[Tuple[int, int]] = []
def push(self, val: int) -> None: m = val if not self.st else min(val, self.st[-1][1]) self.st.append((val, m))
def pop(self) -> None: self.st.pop()
def top(self) -> int: return self.st[-1][0]
def getMin(self) -> int: return self.st[-1][1]class MinStack { constructor() { this.st = []; // [val, minSoFar] }
push(val) { const m = this.st.length === 0 ? val : Math.min(val, this.st[this.st.length - 1][1]); this.st.push([val, m]); }
pop() { this.st.pop(); }
top() { return this.st[this.st.length - 1][0]; }
getMin() { return this.st[this.st.length - 1][1]; }}class MinStack { private Deque<int[]> st;
public MinStack() { st = new ArrayDeque<>(); }
public void push(int val) { int m = st.isEmpty() ? val : Math.min(val, st.peek()[1]); st.push(new int[]{val, m}); }
public void pop() { st.pop(); }
public int top() { return st.peek()[0]; }
public int getMin() { return st.peek()[1]; }}class MinStack { private st: [number, number][] = [];
push(val: number): void { const m = this.st.length === 0 ? val : Math.min(val, this.st[this.st.length - 1][1]); this.st.push([val, m]); }
pop(): void { this.st.pop(); }
top(): number { return this.st[this.st.length - 1][0]; }
getMin(): number { return this.st[this.st.length - 1][1]; }}Editorial#
Carrying the running minimum alongside each value makes getMin trivial. Popping does the right thing for free since the prior frame already stored its own min. Space doubles in the worst case — a fine trade for O(1) queries.
Complexity#
- Time:
O(1)per op. - Space:
O(n).
Concept revision#
Related#