The “Min Stack” problem asks us to design a stack that supports the following operations in constant time:
push(val)
: Pushes the value onto the stack.pop()
: Removes the element on top of the stack.top()
: Gets the top element of the stack.getMin()
: Retrieves the minimum element in the stack.
The challenge is to implement getMin()
efficiently — ideally in O(1) time — rather than scanning through all elements every time.
This problem demonstrates how to augment a standard data structure (a stack) to support additional operations efficiently. It's an important example in data structure design and is frequently asked in interviews to test understanding of auxiliary tracking and state synchronization.
The key idea is to use a second stack to track the minimum value at each level of the main stack. Whenever we push a new value, we also push the new minimum (either the new value or the current minimum, whichever is smaller) onto the second stack.
stk
: stores all values.min_stk
: stores the minimum value at each level.push(val)
:
val
onto stk
.min_stk
is empty, or val <= min_stk[-1]
, push val
onto min_stk
.min_stk[-1]
again to preserve the previous minimum.pop()
:
stk
and min_stk
to keep stacks aligned.top()
: Return the top element of stk
.getMin()
: Return the top element of min_stk
.
Operations: push(5)
, push(3)
, push(7)
, getMin()
, pop()
, getMin()
Time Complexity: O(1) for all operations: push, pop, top, and getMin.
Space Complexity: O(n), where n is the number of elements pushed onto the stack (due to the use of an auxiliary stack).
getMin()
on an empty stack → should be guarded or throw an error depending on the languageThe “Min Stack” problem is a great exercise in augmenting data structures with auxiliary information. By maintaining a parallel stack of minimum values, we ensure constant-time retrieval of the current minimum element — a powerful technique applicable to many similar optimization problems in stack design.