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 所指向的节点,从而实现对栈的修改。
