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.
Constraints:
-231 <= val <= 231 - 1
- Methods
pop
,top
, andgetMin
operations will always be called on non-empty stacks. - At most 3 * 104 calls will be made to
push
,pop
,top
, andgetMin
.
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,-2,null,-2]
Explanation: MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.getMin(); // return -2 minStack.pop(); minStack.getMin(); // return -2
Steps
-
Data Structure: Use two stacks:
dataStack
to store the actual data andminStack
to store the minimum values encountered so far. -
push(val): Push
val
ontodataStack
. IfminStack
is empty orval
is less than or equal to the top ofminStack
, pushval
ontominStack
. -
pop(): Pop the top element from
dataStack
. If the popped element is equal to the top ofminStack
, pop the top element fromminStack
as well. -
top(): Return the top element of
dataStack
. -
getMin(): Return the top element of
minStack
.
Explanation
The key to achieving constant time complexity for getMin
is using the minStack
. minStack
maintains a monotonically decreasing sequence of minimum values seen so far. This ensures that getMin
only needs to access the top of minStack
. Whenever we push a new element, we only push it to minStack
if it's smaller than or equal to the current minimum. When we pop, we only remove from minStack
if the popped element was the current minimum. This maintains the invariant that the top of minStack
is always the minimum element in dataStack
.
Code
#include <stack>
class MinStack {
private:
stack<int> dataStack;
stack<int> minStack;
public:
MinStack() {}
void push(int val) {
dataStack.push(val);
if (minStack.empty() || val <= minStack.top()) {
minStack.push(val);
}
}
void pop() {
if (dataStack.top() == minStack.top()) {
minStack.pop();
}
dataStack.pop();
}
int top() {
return dataStack.top();
}
int getMin() {
return minStack.top();
}
};
Complexity
-
Time Complexity:
push()
: O(1)pop()
: O(1)top()
: O(1)getMin()
: O(1)
-
Space Complexity: O(N), where N is the number of elements in the stack. We use two stacks to store the data, so the space used is proportional to the number of elements.