Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
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.
以下有三种方法:
1 使用两个栈,一个栈存储元素,一个栈存储最小值;
2 使用链表,Node包含val,min,next属性,新添加的元素放在链表头部,不放在尾部
3 使用一个栈,Node包含val,min属性,每次push时比较min与插入值x的大小,再设置新元素的min
还有第四种方法《C++ Solution O(1) Time and O(1) space complexity》
https://leetcode.com/problems/min-stack/discuss/324790/C%2B%2B-Solution-O(1)-Time-and-O(1)-space-complexity
方法1:
//Runtime: 47 ms, faster than 64.83% of Java online submissions for Min Stack.
//Memory Usage: 40.7 MB, less than 32.33% of Java online submissions for Min Stack.
//空间复杂度O(n),时间复杂度O(1),需要额外的栈存储最小值
public class MinStack {
private Stack stack = new Stack<>();
private Stack minStack = new Stack<>();
public MinStack() {
}
public void push(int x) {
stack.push(x);
if (minStack.size() == 0) {
minStack.push(x);
} else {
if (x > minStack.peek()) {
minStack.push(minStack.peek());
} else {
minStack.push(x);
}
}
}
public void pop() {
stack.pop();
minStack.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
public static void main(String[] args) {
MinStack object = new MinStack();
object.push(-2);
object.push(0);
object.push(-1);
System.out.println(object.getMin());
System.out.println(object.top());
object.pop();
System.out.println(object.getMin());
}
}
方法2:
//Runtime: 45 ms, faster than 98.87% of Java online submissions for Min Stack.
//Memory Usage: 40.3 MB, less than 33.72% of Java online submissions for Min Stack.
//空间复杂度O(1),时间复杂度O(1),不需要额外的栈存储最小值
class MinStack {
private class Node {
private int val;
private int min;
private Node next;
public Node(int val, int min) {
this.val = val;
this.min = min;
}
public Node(int val, int min, Node next) {
this.val = val;
this.min = min;
this.next = next;
}
}
private Node cur;
public MinStack() {
}
public void push(int x) {
if (cur == null) {
cur = new Node(x, x);
} else {//新元素的结点,添加在链表头部,然后再用next指向之前的链表
Node head = new Node(x, cur.min > x ? x : cur.min, cur);
cur = head;
}
}
public void pop() {
Node head = cur;
cur = cur.next;
head.next = null;//释放内存
}
public int top() {
return cur.val;
}
public int getMin() {
return cur.min;
}
public static void main(String[] args) {
MinStack object = new MinStack();
object.push(-2);
object.push(0);
object.push(-1);
System.out.println(object.getMin());
System.out.println(object.top());
object.pop();
System.out.println(object.getMin());
}
}
//-2
//-1
//-2
方法3:
//Runtime: 47 ms, faster than 64.83% of Java online submissions for Min Stack.
//Memory Usage: 39.1 MB, less than 40.35% of Java online submissions for Min Stack.
//空间复杂度O(1),时间复杂度O(1),不需要额外的栈存储最小值
class MinStack {
private Stack stack = new Stack<>();
private class Node {
private int val;
private int min;
public Node(int val, int min) {
this.val = val;
this.min = min;
}
}
/** initialize your data structure here. */
public MinStack() {
}
public void push(int x) {
if (stack.empty()) {
stack.push(new Node(x, x));
} else {
if (x < stack.peek().min) {
stack.push(new Node(x, x));
} else {
stack.push(new Node(x, stack.peek().min));
}
}
}
public void pop() {
stack.pop();
}
public int top() {
return stack.peek().val;
}
public int getMin() {
return stack.peek().min;
}
public static void main(String[] args) {
MinStack object = new MinStack();
object.push(-2);
object.push(0);
object.push(-1);
System.out.println(object.getMin());
System.out.println(object.top());
object.pop();
System.out.println(object.getMin());
}
}
//-2
//-1
//-2