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.
Solutions:
(1) two stacks
use dataStack to save the data and the minStack to save the min
PUSH:
* For dataStack: push every new_element
* For minStack:
if the new_element <= minStack.top: minStack.push(new_element) [don't forget equal]
> : pass
POP:
* For dataStack: dataStack.pop()
* For minStack:
minStack.pop when the top==dataStack.pop()
Java:
class MinStack {
/** initialize your data structure here. */
private Stack<Integer> stack;
private Stack<Integer> minStack;
public MinStack() {
stack = new Stack<>();
minStack = new Stack<>();
}
public void push(int x) {
stack.push(x);
if (!minStack.isEmpty()) {
int top = minStack.peek();
//小于的时候才入栈
if (x <= top) {
minStack.push(x);
}
}else{
minStack.push(x);
}
}
public void pop() {
int pop = stack.pop();
int top = minStack.peek();
//等于的时候再出栈
if (pop == top) {
minStack.pop();
}
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
}
// https://leetcode-cn.com/problems/min-stack/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-38/
C++:
class MinStack {
private:
stack<int> s1;
stack<int> s2;
public:
void push(int x) {
s1.push(x);
if (s2.empty() || x <= getMin()) s2.push(x);
}
void pop() {
if (s1.top() == getMin()) s2.pop();
s1.pop();
}
int top() {
return s1.top();
}
int getMin() {
return s2.top();
}
};
// https://leetcode.com/problems/min-stack/discuss/49016/C%2B%2B-using-two-stacks-quite-short-and-easy-to-understand
(2) One stack
the key point is to save previous min when it is updated
(2.1) dataStack only and use a variable to save min
Push previous min to the dataStack when new_element < min
Pop twice when the element == min
Java:
class MinStack {
int min = Integer.MAX_VALUE;
Stack<Integer> stack = new Stack<Integer>();
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;
}
}
// https://leetcode-cn.com/problems/min-stack/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-38/
(2.2) differenceStack save (element - min) and a variable save min
update the min when the element is smaller
(When a smaller element is pushed, a negative digit will be pushed in the differenceStack)
Push diff + min when diff > 0; min when diff < 0
Update min = min - diff when diff < 0
Java:
public class MinStack {
long min;
Stack<Long> stack;
public MinStack(){
stack=new Stack<>();
}
public void push(int x) {
if (stack.isEmpty()) {
min = x;
stack.push(x - min);
} else {
stack.push(x - min);
if (x < min){
min = x; // 更新最小值
}
}
}
public void pop() {
if (stack.isEmpty())
return;
long pop = stack.pop();
//弹出的是负值,要更新 min
if (pop < 0) {
min = min - pop;
}
}
public int top() {
long top = stack.peek();
//负数的话,出栈的值保存在 min 中
if (top < 0) {
return (int) (min);
//出栈元素加上最小值即可
} else {
return (int) (top + min);
}
}
public int getMin() {
return (int) min;
}
}
// https://leetcode-cn.com/problems/min-stack/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-38/
(3) create a new private class that specially contains min as a private variable
For each element in the stack, it can be considered as a node with three features: val, min, next(under the current).
A private variable 'head' means the top element in the stack, so pushing can be considered as creating a new node as head and link head.next to previous head
Java:
class MinStack {
private Node head;
public void push(int x) {
if(head == null)
head = new Node(x, x);
else
head = new Node(x, Math.min(x, head.min), head);
}
public void pop() {
head = head.next;
}
public int top() {
return head.val;
}
public int getMin() {
return head.min;
}
private class Node {
int val;
int min;
Node next;
private Node(int val, int min) {
this(val, min, null);
}
private Node(int val, int min, Node next) {
this.val = val;
this.min = min;
this.next = next;
}
}
}
// https://leetcode.com/problems/min-stack/discuss/49010/Clean-6ms-Java-solution
(4) save the corresponding min for each element
for example, in python,save (data, min) in []
so, the last element in the list means (top, min)
Python:
lass MinStack:
def __init__(self):
self.q = []
# @param x, an integer
# @return an integer
def push(self, x):
curMin = self.getMin()
if curMin == None or x < curMin:
curMin = x
self.q.append((x, curMin));
# @return nothing
def pop(self):
self.q.pop()
# @return an integer
def top(self):
if len(self.q) == 0:
return None
else:
return self.q[len(self.q) - 1][0]
# return self.q[- 1][0]
# @return an integer
def getMin(self):
if len(self.q) == 0:
return None
else:
return self.q[len(self.q) - 1][1]
# return self.q[- 1][1]
# https://leetcode.com/problems/min-stack/discuss/49022/My-Python-solution