题目:
https://leetcode-cn.com/problems/min-stack/
本题难点在于 getMin(),如何快速找到当前栈中最小元素,如果每次在调用 getMin() 的时候才去寻找,时间复杂度较高,所以思考的方向应该是在 push() 和 pop() 时候就去计算最小值并记录。
题解一:
借助辅助栈,我们向目标栈中 push 一个元素时,向辅助栈中 push min(当前目标栈中最小值, 入栈元素),这样辅助栈顶元素就是目标栈最小值,目标栈 pop 元素时,辅助栈也同样 pop 元素。
class MinStack {
private static Stack<Integer> stack;
private static Stack<Integer> minStack;
/** initialize your data structure here. */
public MinStack() {
stack = new Stack();
minStack = new Stack<>();
}
public void push(int val) {
stack.push(val);
if (minStack.isEmpty()) {
minStack.push(val);
} else {
minStack.push(Math.min(minStack.peek(), val));
}
}
public void pop() {
stack.pop();
minStack.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
}
时间复杂度:O(1).
空间复杂度:O(N).
题解二:
我们把"竖"着的栈,看作"横"着的链表,栈中的一个元素看做成链表中的一个节点,每个节点保存当前节点值、最小值以及上一节点指针。
class MinStack {
private Node node;
/** initialize your data structure here. */
public MinStack() {}
public void push(int val) {
if (node == null) {
node = new Node(val, val);
} else {
Node newNode = new Node(val, Math.min(node.minValue, val));
newNode.prevNone = node;
node = newNode;
}
}
public void pop() {
node = node.prevNone;
}
public int top() {
return node.value;
}
public int getMin() {
return node.minValue;
}
private class Node {
int value;
int minValue;
Node prevNone;
public Node(int value, int minValue) {
this.value = value;
this.minValue = minValue;
}
}
}
node 表示链表的头节点,在push的时候需要更新头节点,在pop时需要删除当前头节点使上一节点变为新的头节点。
时间复杂度:O(1).
空间复杂度:O(N).