image-20210904103317969.png

    这个题大体上和实现了一个栈没有什么区别,而且还不用考虑栈为空的情况。我们需要维护一个变量来记录栈的最小值。

    开始的想法:最开始我想,只要在MinStack中维护一个成员变量min就行了吧,只要每次push元素的时候都进行比较更新不就行了,实现到pop()操作的时候,我突然意识到这样并不行,如果栈顶元素刚好是最小元素,那么当我把栈顶元素删除后,此时栈的最小元素就不得而知了。所以说只全局维护一个变量是不行的。

    改进的思路:由于只维护当前栈的最小元素是不行的,那么我们就要像动态规划那样,储存栈每个状态的最小值,当前栈的最小值可以由上一个状态得到,递推式为dp[i] = min(dp[i-1], val),这样我们就解决了上面所出现的问题,不会因为删除最小元素后,不知道删除后栈的最小元素了。

    具体实现方案:我们可以在MinStack中维护一个list来保存最小栈每个状态下的最小值。然而我们可以用另外一种更为巧妙的方法来实现,我们在用于构建栈的Node节点中,添加一个属性curStackMin的属性,这样同样可以达到上述的效果,使用Node来保存最小值的信息。

    1. class MinStack {
    2. private Node head;
    3. /** initialize your data structure here. */
    4. public MinStack() {}
    5. public void push(int val) {
    6. if(head == null){
    7. head = new Node(val, val);
    8. }else{
    9. head = new Node(val, Math.min(head.curStackMin, val), head);
    10. }
    11. }
    12. public void pop() {
    13. head = head.next;
    14. }
    15. public int top() {
    16. return head.val;
    17. }
    18. public int getMin() {
    19. //本题不用考虑空栈情况
    20. //if(head == null){}
    21. return head.curStackMin;
    22. }
    23. private class Node{
    24. int val;
    25. //用于保存,该结点加入后,此时栈的最小值
    26. int curStackMin;
    27. Node next;
    28. private Node(){
    29. }
    30. private Node(int val, int curStackMin){
    31. this.val = val;
    32. this.curStackMin = curStackMin;
    33. }
    34. private Node(int val, int curStackMin, Node next){
    35. this.val = val;
    36. this.curStackMin = curStackMin;
    37. this.next = next;
    38. }
    39. }
    40. }