Sweaty Imposter

Min Stack

MediumStackNeetCode 150MidOpen on LeetCodeUpdated

Design a class MinStack: a last-in, first-out collection of integers that can also report its smallest element instantly. push(val) adds val on top, pop() removes the top element, top() returns the top element without removing it, and getMin() returns the smallest element currently stored. pop, top and getMin are only called when at least one element is stored. Every operation must run in O(1) time, so scanning the elements inside getMin is not allowed.

Examples

MinStack(); push(-2); push(0); push(-3); getMin(); pop(); top(); getMin() returns -3, 0, -2

After the three pushes the smallest value is -3. pop() removes -3, which leaves 0 on top and makes -2 the smallest value again.

MinStack(); push(2); push(1); push(1); pop(); getMin() returns 1

Two copies of 1 are pushed. Popping one of them still leaves a 1 stored, so getMin() must return 1, not 2.

Constraints

  • -2^31 <= val <= 2^31 - 1
  • pop, top and getMin are only called when at least one element is stored.
  • At most 3 * 10^4 calls will be made to push, pop, top and getMin.

Hints

Hint 1

A single 'current minimum' variable works until the minimum itself is popped. What would you need to have remembered to know the minimum of what remains?

Hint 2
A pointer toward the approach
Hint 3
The full approach, step by step

Drill This: Your Approach First

Approach

The minimum only changes when elements are pushed or popped at the top, so you can remember the minimum at every height. Keep a second stack in lockstep with the main one: each push also records min(val, previous minimum), and each pop removes from both. getMin just reads the top of the min stack. Every operation is O(1) time, and the extra stack costs O(n) space.

Time

O(1) per operation

Space

O(n)

Pitfall

Tracking a single min variable: once that minimum is popped, the previous one can't be recovered without a scan. Pushing to the min stack only when val is strictly smaller breaks on duplicate minimums, so push on val <= current min, or on every push as here.

Solutions

class MinStack {
    private final Deque<Integer> stack = new ArrayDeque<>();
    private final Deque<Integer> mins = new ArrayDeque<>();

    public void push(int val) {
        stack.push(val);
        mins.push(mins.isEmpty() ? val : Math.min(val, mins.peek()));
    }

    public void pop() {
        stack.pop();
        mins.pop();
    }

    public int top() {
        return stack.peek();
    }

    public int getMin() {
        return mins.peek();
    }
}
Drill This