每日一题算法:MinStack 2020.05.12

本文探讨了LeetCode每日一题算法中的MinStack问题,分析了初次实现的空间和时间复杂度,并提出用数组替代系统栈以降低空间复杂度。在尝试用数组实现栈的过程中,遇到了数组扩容和初始化栈顶位置的问题,以及在处理最小值更新时的bug。最终通过调试解决了这些问题,但实际内存优化并未如预期。
摘要由CSDN通过智能技术生成

每日一题算法MinStack:2020.05.12

在这里插入图片描述

class MinStack {

    private static Stack<Integer> stack;
    /** initialize your data structure here. */
   public MinStack() {
        stack=new Stack<Integer>();
    }

    public void push(int x) {
        stack.push(x);
    }

    public void pop() {
        stack.pop();
    }

    public int top() {
        return stack.get(stack.size()-1);
    }

    public int getMin() {
        int index=0;
        int min=stack.get(0);
        for (int i=0;i<stack.size();i++){
            if (stack.get(i)<min){
                min=stack.get(i);
                index=i;
            }

        }
        return stack.get(index);
    }
}

初次版本

成功,但是并不是最好的办法

在这里插入图片描述
可以看出,这种方法明显不够优秀,现在想一想,从空间复杂度或者时间复杂度上如何去优化。

空间复杂度,不使用系统给的栈,因为这个栈是实现了list接口的,能不能用数组实现一个栈呢?答案是肯定的,但是实际上会非常复杂,数组会便于查找最小数但是不适合入栈和出栈,但是从空间复杂度上来说是最小的。

试着用数组实现一个栈。

发现问题!

经过思考后发现,如果一个数组长度为10,需要压入一个进栈时,需要再创建一个长度增加一个的数组,这样相当于复制了一个数组,也许可以通过StringBuilder的扩容方式来扩展数组,给数组设定一个实际的长度,如果超过了这个大小,那么长度翻倍,然后数组的后方有许多的空位。这样可以节省很多扩容的时间。

在这里插入图片描述

栈大小的初始大小就设置为16,因为StringBuilder设置的就是16,这么设置肯定是有道理的。

所以,如果要用数组来实现栈的话,肯定需要2个变量,一个表示栈顶的位置,一个表示最小值,栈的实际大小不需要变量,因为可以直接通过数组的长度获得。

实现之后发现了leecode的一个bug,输的好冤。

在这里插入图片描述

class MinStack {
    private static int[] stack;
    private static int min=Integer.MAX_VALUE;
    private static int topIndex;

    public MinStack(){
        stack=new int[16];
    }
    public void push(int x){
        if (x<min)
            min=x;
        if (topIndex+1>=stack.length)
            remake();
        topIndex++;
        stack[topIndex]=x;
    }
    public void pop(){
        if (stack[topIndex]==min)
            findMin();
        topIndex--;

    }
    public int top(){
        return stack[topIndex];
    }
    public int getMin(){
        return min;
    }
    public void remake(){
       int[] newstack=new int[stack.length*2];
       for (int i=0;i<stack.length;i++){
           newstack[i]=stack[i];
       }
       stack=newstack;
    }
    public void findMin(){
        min=stack[0];
        for (int i=0;i<topIndex-1;i++){
            if (stack[i]<=min)
                min=stack[i];
        }
    }
}

结果不知道是不是正确的,因为存在bug,没能完成验证

找到了bug所在,在leecode里写算法千万不要用静态全局变量!!!
出现错误
在这里插入图片描述
错误出现的位置,栈中的第2个0弹出时,最小值还是0.
在这里插入图片描述
经过调试,发现是由于设置的初始栈顶位置下标为0,而在插入之前会将下标+1,所以实际上第一个值的位置是在下标1的位置。
修改方式,初始栈顶位置下标改为-1或者在插入之后修改栈顶的位置。

出现错误
在这里插入图片描述
错误原因分析,在所有元素出栈时没有将最小值标记重置,导致新值入栈时显示的最小值不是新的最小值(比之前的最小值大)。
修改方式:在栈顶下标为0时出栈操作会将最小值重置为最大整数。

if(topIndex==0)
            min=Integer.MAX_VALUE;
        else {
            min=stack[0];
            for (int i=0;i<=topIndex-1;i++){
                if (stack[i]<=min)
                    min=stack[i];
            }
        }
    }

通过,本以为自己写的数据结构会更加节省内存,没想到没有实现。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值