THN Interview Prep

155. Min Stack

At a Glance

  • Topic: stack
  • Pattern: Stack + auxiliary min history
  • Difficulty: Medium
  • Companies: Amazon, Google, Meta, Bloomberg, Microsoft
  • Frequency: High
  • LeetCode: 155

Problem (one-liner)

Design a stack supporting push, pop, top, and getMin in amortized O(1) per operation. pop and top follow normal stack behavior.

Recognition Cues

  • "Min in constant time" alongside stack ops
  • Duplicate minimum values matter — track counts or store pairs (value, currentMin)
  • Second stack of mins or store (x, minAfterPush)

Diagram

At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.

Loading diagram…

Approaches

  • Brute force — scan entire stack for min — O(n) per getMin.
  • Better — heap — breaks LIFO pairing unless augmented.
  • OptimalO(1) push/pop/min — parallel min-stack storing minimum snapshot per depth.

Optimal Solution

Go

type MinStack struct {
	values   []int
	minStack []int
}

func Constructor() MinStack {
	return MinStack{
		values:   []int{},
		minStack: []int{},
	}
}

func (stack *MinStack) Push(val int) {
	stack.values = append(stack.values, val)
	if len(stack.minStack) == 0 || val <= stack.minStack[len(stack.minStack)-1] {
		stack.minStack = append(stack.minStack, val)
	}
}

func (stack *MinStack) Pop() {
	top := stack.values[len(stack.values)-1]
	stack.values = stack.values[:len(stack.values)-1]
	if top == stack.minStack[len(stack.minStack)-1] {
		stack.minStack = stack.minStack[:len(stack.minStack)-1]
	}
}

func (stack *MinStack) Top() int {
	return stack.values[len(stack.values)-1]
}

func (stack *MinStack) GetMin() int {
	return stack.minStack[len(stack.minStack)-1]
}

JavaScript

class MinStack {
	constructor() {
		this.values = [];
		this.minValues = [];
	}
	push(value) {
		this.values.push(value);
		const priorMin = this.minValues.at(-1);
		if (this.minValues.length === 0 || value <= priorMin) {
			this.minValues.push(value);
		}
	}
	pop() {
		const top = this.values.pop();
		if (top === this.minValues.at(-1)) {
			this.minValues.pop();
		}
	}
	top() {
		return this.values.at(-1);
	}
	getMin() {
		return this.minValues.at(-1);
	}
}

Walkthrough

Push 0, 1, 0: min stack mirrors [0], still [0] after duplicate handling variant — above duplicates min only when <= top min.

Invariant: minStack[len-1] equals minimum of values stack contents.

Edge Cases

  • Repeated minimum pushes and pops
  • Negative values
  • Single element

Pitfalls

  • Comparing with < instead of <= — duplicate minima break pops
  • Desynchronizing values and minStack on edge cases

Similar Problems

Variants

  • Max stack symmetrically.
  • Median stack — usually two heaps; not constant-time with pure stacks.

Mind-Map Tags

#stack #auxiliary-stack #min-tracking #amortized-o1 #design

Last updated on

Spotted something unclear or wrong on this page?

On this page