1、最小栈
辅助栈
引入一个辅助栈,专门存储最小值,与主栈同步进出 需要注意辅助栈的进栈规则
Deque<Integer> xStack;
Deque<Integer> minStack;
public MinStack() {
xStack = new LinkedList<Integer>();
minStack = new LinkedList<Integer>();
minStack.push(Integer.MAX_VALUE);
}
public void push(int x) {
xStack.push(x);
minStack.push(Math.min(minStack.peek(), x)); //取最小值,当
}
public void pop() {
xStack.pop();
minStack.pop();// 只会存储最小值,所以可以出栈
}
public int top() {
return xStack.peek();
}
public int getMin() {
return minStack.peek();
}
双插法
与辅助栈类似,同时存储当前元素和当前的最小值,出栈时出两次,获得最小值时获取当前的倒数第二个数字
Stack<Integer> stack = new Stack<Integer>();
public void push(int x) {
if(stack.isEmpty()){
stack.push(x);
stack.push(x);
}else{
int tmp = stack.peek();
stack.push(x);
if(tmp<x){
stack.push(tmp);
}else{
stack.push(x);
}
}
}
public void pop() {
stack.pop();
stack.pop();
}
public int top() {
return stack.get(stack.size()-2);
}
public int getMin() {
return stack.peek();
}
适用链表实现
上述两种方式都是使用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;
}
}
}
head 是该栈的栈顶元素,它的作用是指向栈顶元素的节点。在进行元素的入栈和出栈操作时,会改变 head 所指向的节点,从而实现对栈的修改。