1、最小栈

力扣

辅助栈

引入一个辅助栈,专门存储最小值,与主栈同步进出 需要注意辅助栈的进栈规则

  1. Deque<Integer> xStack;
  2. Deque<Integer> minStack;
  3. public MinStack() {
  4. xStack = new LinkedList<Integer>();
  5. minStack = new LinkedList<Integer>();
  6. minStack.push(Integer.MAX_VALUE);
  7. }
  8. public void push(int x) {
  9. xStack.push(x);
  10. minStack.push(Math.min(minStack.peek(), x)); //取最小值,当
  11. }
  12. public void pop() {
  13. xStack.pop();
  14. minStack.pop();// 只会存储最小值,所以可以出栈
  15. }
  16. public int top() {
  17. return xStack.peek();
  18. }
  19. public int getMin() {
  20. return minStack.peek();
  21. }

双插法

与辅助栈类似,同时存储当前元素和当前的最小值,出栈时出两次,获得最小值时获取当前的倒数第二个数字

  1. Stack<Integer> stack = new Stack<Integer>();
  2. public void push(int x) {
  3. if(stack.isEmpty()){
  4. stack.push(x);
  5. stack.push(x);
  6. }else{
  7. int tmp = stack.peek();
  8. stack.push(x);
  9. if(tmp<x){
  10. stack.push(tmp);
  11. }else{
  12. stack.push(x);
  13. }
  14. }
  15. }
  16. public void pop() {
  17. stack.pop();
  18. stack.pop();
  19. }
  20. public int top() {
  21. return stack.get(stack.size()-2);
  22. }
  23. public int getMin() {
  24. return stack.peek();
  25. }

适用链表实现

上述两种方式都是使用Java自带的数据结构,还可以自定义数据结构

  1. class MinStack {
  2. private Node head; // 定义栈顶元素节点
  3. // 元素入栈操作
  4. public void push(int x) {
  5. // 如果栈为空,则将新元素作为栈顶元素
  6. if (head == null) {
  7. head = new Node(x, x);
  8. } else {
  9. // 如果栈不为空,则将新元素作为新的栈顶元素,并更新最小值
  10. head = new Node(x, Math.min(x, head.min), head);
  11. }
  12. }
  13. // 元素出栈操作
  14. public void pop() {
  15. head = head.next; // 将栈顶元素指向下一个节点,实现出栈操作
  16. }
  17. // 获取栈顶元素的值
  18. public int top() {
  19. return head.val;
  20. }
  21. // 获取栈中的最小值
  22. public int getMin() {
  23. return head.min;
  24. }
  25. // 定义链表节点类
  26. private class Node {
  27. int val; // 节点的值
  28. int min; // 节点前缀的最小值
  29. Node next; // 节点的后继节点
  30. // 构造函数
  31. private Node(int val, int min) {
  32. this(val, min, null);
  33. }
  34. private Node(int val, int min, Node next) {
  35. this.val = val;
  36. this.min = min;
  37. this.next = next;
  38. }
  39. }
  40. }

head 是该栈的栈顶元素,它的作用是指向栈顶元素的节点。在进行元素的入栈和出栈操作时,会改变 head 所指向的节点,从而实现对栈的修改。