Min Stack medium
Problem Statement
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
Implement the MinStack
class:
MinStack()
initializes the stack object.void push(int val)
pushes the elementval
onto the stack.void pop()
removes the element on top of the stack.int top()
gets the top element of the stack.int getMin()
retrieves the minimum element in the stack.
Example 1:
Input
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
Output
[null,null,null,null,-3,null,0,-2]
Explanation
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); // return -3
minStack.pop();
minStack.top(); // return 0
minStack.getMin(); // return -2
Example 2:
Input
["MinStack","push","push","getMin","pop","getMin"]
[[], [2],[0],[],[],[]]
Output
[null,null,null,0,null,2]
Explanation
MinStack minStack = new MinStack();
minStack.push(2);
minStack.push(0);
minStack.getMin(); // return 0
minStack.pop();
minStack.getMin(); // return 2
Steps:
- Data Structure: Use two stacks:
stack
to store the elements andmin_stack
to store the minimum element at each stage. - push(val): Push
val
ontostack
. Ifmin_stack
is empty orval
is less than or equal to the top ofmin_stack
, pushval
ontomin_stack
as well. - pop(): Pop the top element from
stack
. If the popped element is equal to the top ofmin_stack
, pop frommin_stack
too. - top(): Return the top element of
stack
. - getMin(): Return the top element of
min_stack
.
Explanation:
The key idea is to maintain a second stack (min_stack
) that always keeps track of the minimum element encountered so far. Whenever we push an element, we also check if it's the new minimum and push it onto min_stack
. When we pop, we check if the popped element is the current minimum; if it is, we pop it from min_stack
as well. This ensures min_stack
always contains the current minimum element at its top.
Code:
class MinStack:
def __init__(self):
self.stack = []
self.min_stack = []
def push(self, val: int) -> None:
self.stack.append(val)
if not self.min_stack or val <= self.min_stack[-1]:
self.min_stack.append(val)
def pop(self) -> None:
if self.stack:
if self.stack[-1] == self.min_stack[-1]:
self.min_stack.pop()
self.stack.pop()
def top(self) -> int:
if self.stack:
return self.stack[-1]
return None
def getMin(self) -> int:
if self.min_stack:
return self.min_stack[-1]
return None
Complexity:
- Time Complexity:
push()
,pop()
,top()
,getMin()
: O(1) All operations involve accessing the top of the stack, which is a constant-time operation.
- Space Complexity: O(N), where N is the number of elements in the stack. In the worst case, both
stack
andmin_stack
can store up to N elements.