剑指 Offer 30 包含min函数的栈

依旧是栈,由于先做了09,所以看这个题时,优先考虑了使用双栈,同样第一个栈为数据栈,第二个栈为辅助栈(最小栈)

该题的评论题解中,大佬给出的动画、白话文题解更为通俗、详细,这里自己就写的简单一些,自己能够理解即可

首先 理解数据栈和辅助栈(最小栈)的作用,顾名思义,数据栈就是所有的元素都压入数据栈,而最小栈就是压入每次数据栈输入元素之后的数据栈中元素的最小值,如图所示

最初时,往数据栈中压入元素 2

压入之后,由于数据栈中只有一个元素 2 ,那么此时最小栈中的最小元素则为 2

再次压入一个元素 3 ,此时数据栈中有2、3两个元素

那么最小栈此时压入的就是数据栈中元素的最小值,此时数据栈中只有2、3 两个元素,最小值为2,则最小栈中继续压入元素 2

如果继续往数据栈中压入元素 1 ,那么此时 数据栈元素为:2、3、1

那么此时数据栈中的三个元素的最小值就变成了1,所以往最小栈中压入的数据就为1

通过这样的步骤我们可以发现,最小栈的栈顶元素永远是数据栈中最小的元素 

这样我们就可以通过判断的方式,来写出push的方法

而pop则是双栈元素都进行pop

top则返回的是数据栈的栈顶元素

min根据上面的红色总结,则返回的是 最小栈的栈顶元素

根据思路写出代码

class MinStack {

    Stack<Integer> data_stack;
    Stack<Integer> min_stack;

    /** initialize your data structure here. */
    public MinStack() {
        data_stack = new Stack<>();
        min_stack = new Stack<>();
    }
    
    public void push(int x) {
        if(min_stack.isEmpty()){ //最小栈为空,说明数据栈也为空,则把元素压入最小栈
            min_stack.push(x);
        }else{ //最小栈不为空,说明数据栈也不为空,而最小栈栈顶元素为数据栈的最小元素,则进行判断比较
            if(min_stack.peek() > x){ //最小栈的栈顶元素 > x ,说明 x 更小,应该压入最小栈
                min_stack.push(x);
            }else{
                //最小栈的栈顶元素 < x ,说明 x 更大,则最小栈压入上次记录的最小元素
                min_stack.push(min_stack.peek());
            } 
        }
        data_stack.push(x);  
    }
    
    public void pop() {
        data_stack.pop();
        min_stack.pop();
    }
    
    public int top() {
        return data_stack.peek();
    }
    
    public int min() {
        return min_stack.peek();
    }
}

这里需要区别 pop() 和 peek()

pop() 是返回栈顶的元素,并在进程中删除它。

peek() 则是返回栈顶的元素,但不在堆栈中删除它。

isEmpty() 则是判断是否为空,如果栈是空的,则返回true,如果栈中含有元素,则返回false

猜你喜欢

转载自blog.csdn.net/Sean_Asu/article/details/122890280