We need a stack that supports the usual push, pop, and top operations and also returns the minimum element at any time, with every operation running in O(1). The standard stack operations are easy. The hard part is getMin.
With a plain stack, finding the minimum means scanning every element, which is O(n). The question is how to track the minimum as elements come and go, without ever scanning.
The minimum can only change in two situations: when we push an element smaller than the current minimum, or when we pop an element that was the current minimum. So we need a way to recover what the minimum was before the popped element arrived.
-2^31 <= val <= 2^31 - 1 → Values span the full 32-bit signed integer range, including the minimum value -2147483648. A sentinel value chosen to mean "empty" could collide with a real input, so avoid that design.3 * 10^4 calls → The problem requires O(1) per operation regardless of call volume, so we need a design that tracks the minimum incrementally rather than recomputing it.Use a regular stack for push, pop, and top, then scan the entire stack whenever getMin is called. This ignores the O(1) requirement for getMin, but it establishes a correct baseline.
Push, pop, and top are already O(1) with a standard stack. Only getMin is expensive: each call iterates through all elements currently in the stack to find the smallest one.
The brute force is correct but getMin scans the entire stack on every call. The next approach tracks the minimum as elements are pushed and popped, so getMin never scans.
The minimum of a stack depends only on the elements currently in it, and because we only add and remove from the top, those elements are always a prefix of the push history. If we record what the minimum was at each level of the stack, popping an element restores the previous minimum.
One way to do this is with a second stack, the min stack. Every time we push a value, we also push the current minimum onto the min stack. When we pop, we pop from both. The top of the min stack always holds the current minimum.
The min stack maintains one invariant: at any stack height h, the value at height h in the min stack is the minimum of all elements from the bottom up to height h. When we pop an element, the height drops by one, and the new top of the min stack already holds the correct minimum for that reduced height, computed back when that level was pushed.
This is a prefix minimum over the push history. Because stack operations only affect the top, each level's minimum never depends on elements pushed later, so the invariant holds through any sequence of pushes and pops.
stack) and one for tracking minimums (minStack).The two-stack approach gives O(1) for every operation but maintains two separate data structures kept in sync. The next approach folds them into a single stack that stores pairs.
Instead of maintaining two separate stacks, store pairs of (value, currentMin) in a single stack. Each entry carries its own minimum snapshot. This produces the same answers as the two-stack approach with one data structure, which removes the need to keep two stacks in sync.