题目

设计一个支持 pushpoptop 操作,并能在常数时间内检索到最小元素的栈。

  • push(x) —— 将元素 x 推入栈中。
  • pop() —— 删除栈顶的元素。
  • top() —— 获取栈顶元素。
  • getMin() —— 检索栈中的最小元素。

    数据

    ``` 输入: [“MinStack”,”push”,”push”,”push”,”getMin”,”pop”,”top”,”getMin”] [[],[-2],[0],[-3],[],[],[],[]]

输出: [null,null,null,null,-3,null,0,-2]

解释: MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); —> 返回 -3. minStack.pop(); minStack.top(); —> 返回 0. minStack.getMin(); —> 返回 -2.

  1. <a name="7qy3t"></a>
  2. # 解题思路
  3. 采用一个 `List` 来实现栈,一个 `List` 来保存栈的信息:数据在栈中的位置,数据本身,栈的最小值对应的数据放在min末尾,如下图:-2,0,-3分别入栈后,min的变化<br />![Stack.png](https://cdn.nlark.com/yuque/0/2020/png/661000/1587993786294-e3a68804-9119-4779-b80f-7ae0db28b395.png#align=left&display=inline&height=405&margin=%5Bobject%20Object%5D&name=Stack.png&originHeight=405&originWidth=508&size=10752&status=done&style=none&width=508)
  4. 1. -2 入栈,-2在栈中的位置与值本身写入 `min` 中
  5. 1. 0 入栈,由于-2比0大,所以在栈中,-2最小,因此需要把{1,0}插入到{0,-2}前,保证 `min` 末尾存储栈的最小值信息
  6. 1. -3 入栈,由于-3是最小的,所以直接加在 `min` 末尾
  7. <a name="ppzGF"></a>
  8. # 代码
  9. ```java
  10. import java.util.ArrayList;
  11. import java.util.List;
  12. class MinStack {
  13. private List<Integer> data;
  14. private List<Node> min;
  15. /**
  16. * initialize your data structure here.
  17. */
  18. public MinStack() {
  19. data = new ArrayList<>();
  20. min = new ArrayList<>();
  21. }
  22. public void push(int x) {
  23. data.add(x);
  24. if (min.isEmpty()) {
  25. min.add(new Node(0, x));
  26. } else {
  27. Node last = min.get(min.size() - 1);
  28. if (last.value < x) { //如果入栈的数比min末尾的数据大,则在min末尾前插入新入栈的数据
  29. min.set(min.size() - 1, new Node(min.size(), x));
  30. min.add(last);
  31. } else //如果入栈的数为最小值,直接插入min数组中
  32. min.add(new Node(min.size(), x));
  33. }
  34. }
  35. public void pop() {
  36. // 在min数组中,出栈的数据要么在末尾,要么在末尾-1的位置
  37. if (min.get(min.size() - 1).index == data.size() - 1) { //出栈的数据在min末尾
  38. min.remove(min.size() - 1);
  39. } else {
  40. Node last = min.get(min.size() - 1);
  41. min.set(min.size() - 2, last);
  42. min.remove(min.size() - 1);
  43. }
  44. data.remove(data.size() - 1);
  45. }
  46. public int top() {
  47. return data.get(data.size() - 1);
  48. }
  49. public int getMin() {
  50. return min.get(min.size() - 1).value;
  51. }
  52. class Node {
  53. public int index, value;
  54. public Node(int index, int value) {
  55. this.index = index;
  56. this.value = value;
  57. }
  58. }
  59. }
  60. /**
  61. * Your MinStack object will be instantiated and called as such:
  62. * MinStack obj = new MinStack();
  63. * obj.push(x);
  64. * obj.pop();
  65. * int param_3 = obj.top();
  66. * int param_4 = obj.getMin();
  67. */