Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
- push(x) -- Push element x onto stack.
- pop() -- Removes the element on top of the stack.
- top() -- Get the top element.
- getMin() -- Retrieve the minimum element in the stack.
Example:
MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); --> Returns -3. minStack.pop(); minStack.top(); --> Returns 0. minStack.getMin(); --> Returns -2.
Solution:
Method 1: Two Stacks
We use one stack to store the value and one stack to store the current min value.
In each push operation, we push the value x to the stack and an updated min value to the min stack.
When we pop a value from the stack, we also pop the current min value from the min stack.
Code:
public class MinStack { private Stack<Integer> stack; private Stack<Integer> min; /** initialize your data structure here. */ public MinStack() { stack = new Stack<>(); min = new Stack<>(); } public void push(int x) { if (stack.isEmpty()) { stack.push(x); min.push(x); return; } stack.push(x); min.push(Math.min(min.peek(), x)); } public void pop() { stack.pop(); min.pop(); } public int top() { return stack.peek(); } public int getMin() { return min.peek(); } } /** * Your MinStack object will be instantiated and called as such: * MinStack obj = new MinStack(); * obj.push(x); * obj.pop(); * int param_3 = obj.top(); * int param_4 = obj.getMin(); */
Method 2: One Stack
We have a global min to store the current min value.
When we want to push a value x into the stack, we first check if it is smaller than min.
If it is smaller, we push the min value into the stack and update the min. Then we push x into the stack.
When we pop a value, we check if it equals to min. If so, we need to pop again to retrieve the previous min value and update to the current min.
Code:
public class MinStack { private Stack<Integer> stack; private int min; /** initialize your data structure here. */ public MinStack() { stack = new Stack<>(); min = Integer.MAX_VALUE; } public void push(int x) { if (x <= min) { stack.push(min); min = x; } stack.push(x); } public void pop() { if (stack.pop() == min) { min = stack.pop(); } } public int top() { return stack.peek(); } public int getMin() { return min; } } /** * Your MinStack object will be instantiated and called as such: * MinStack obj = new MinStack(); * obj.push(x); * obj.pop(); * int param_3 = obj.top(); * int param_4 = obj.getMin(); */