算法学习笔记(十三)

栈的例题

实现一个栈,该栈带有出栈、入栈、取最小元素3个方法。要保证这3个方法的时间复杂度是O(1)。
在这里插入图片描述

思路一:
1.创建一个整型变量min,用来存储栈中的最小元素。当第一个元素进栈时,把进栈元素赋值给min,即把栈中唯一的元素当做最小值。
在这里插入图片描述

2.之后每当一个新元素进栈,就让新元素和min比较大小。如果新元素小于min,则Min等于新进栈的元素;如果新元素大于或等于min,则不做改变。
在这里插入图片描述
在这里插入图片描述

3.当调用getMin方法时,直接返回min的值即可。

此时,该方法采用临时变量暂存栈的最小值,但是只考虑到了进栈的场景,却没有考虑出栈的场景。

原本,栈中最小的元素是3,min变量记录的值也是3.

在这里插入图片描述

这时,栈顶元素出栈了。
在这里插入图片描述

此时的Min变量应该等于几呢?
虽然此时的最小元素是4,但是程序并不知道。

详细的解法步骤如下:
1.设原有的栈叫作栈A,此时创建一个额外的“备胎”栈B,用于辅助栈A。
2.当第一个元素进入栈A时,让新元素也进入栈B。这个唯一的元素是栈A的当前最小值。
3.之后,每当新元素进入栈A时,比较新元素和栈A当前最小值的大小,如果小于栈A当前最小值,则让新元素进入栈B,此时栈B的栈顶元素就是栈A当前最小值。
4.每当栈A有元素出栈时,如果出栈元素是栈A当前最小值,则让栈B的栈顶元素也出栈,此时栈B余下的栈顶元素所指向的, 是栈A当中原本第2小的元素,代替刚才的出栈元素成为栈A的当前最小值。(备胎转正)。

5.当调用getmain方法时,返回栈B的栈顶所存储的值,这也是栈A的最小值。
显然,这个方法中进栈、出栈、取最小值的时间复杂度时O(1),最坏情况空间复杂度时O(n).
代码:

public class proStack {
    private Stack<Integer> mainStack = new Stack<Integer>();
    private Stack<Integer> minStack = new Stack<Integer>();

    /**\
     * 入栈操作
     * @param element
     */
    public void  push(int element){
        mainStack.push(element);
        //如果辅助栈未空,或者新元素小于或等于辅助栈栈顶,则将新元素压入辅助栈
        if (minStack.empty()||element<=minStack.peek()){
            minStack.push(element);
        }
    }

    public Integer pop(){
        //如果出栈元素和辅助栈栈顶元素值相等,辅助栈出栈
        if (mainStack.peek().equals(minStack.peek())){
            minStack.pop();
        }
        return mainStack.pop();
    }

    public int getMin() throws  Exception{
        if (mainStack.empty()){
            throw new Exception("stack is empty");
        }
        return minStack.peek();
    }

    public static void main(String[] args) {
        MinStack stack = new MinStack();
        stack.push(4);
        stack.push(9);
        stack.push(7);
        stack.push(3);
        stack.push(8);
        stack.push(5);
        System.out.println(stack.getMin());


    }
}

这段代码的第一个输出是3,因为当时的最小值是3,
第二个输出是4,因为元素3出栈后,最小值是4。
坚持就是胜利。(以上例题来自网上资料,只是记录学习。)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值