0
点赞
收藏
分享

微信扫一扫

设计最小栈,即有栈的基本操作push,pop,peek,还有返回栈中最小值的功能getMin

设计最小栈,即有栈的基本操作push,pop,peek,还有返回栈中最小值的功能getMin

提示:之前我们说系统栈就正常push,pop和peek
现在需要设计一个最小栈,o(1)速度返回当前栈中的最小值。


文章目录

题目

设计最小栈,即有栈的基本操作push,pop,peek,
还有一个新函数,即:返回当前栈中的最小值的getMin()


一、审题

示例:比如压入2 3 1 4 5
对应的栈中最小值应该是:
2 2 1 1 1
请实现这样的栈:最小栈


二、最小栈的设计方法

实际上,最小栈,根据示例也能看出来,也就是2个系统栈:数据栈data和最小值栈min
data负责日常push,pop和peek功能
每次push时,需要对比此时新来的value和min中栈顶那个值的大小
如果:
(1)value>=min栈顶那个值:则需要把min栈顶赋值给value,存入min,代表最小值已然不变
(2)value<min栈顶那个值:则确实来了一个新的最小值,直接将value存入min即可,代表新的最小值来了
这样的话,data自然干自己的
min保证数量和data一样,而且,data目前这范围内最小值,都在min放好的,不会乱
在这里插入图片描述
看上图就明白
当data中只有2,此时min必然也是只有2,它就是最小值
当data中有32,此时最小值自然也是2,
当data中有132,来了一个1比2小,自然1从今往后就是最小值
之后来的数大于等于1,min中栈顶也自然存1
除非来了个0,或者更小的,那就是让min再放更小的

(3)弹出的时候,data自己常规骚操作,然后min也要跟着弹出一个,保证范围内数量跟data一致;
在这里插入图片描述

手撕代码:

//复习最小栈,很简单,就是另外拿一个系统栈,放每次输入的最小值,即可
    public static class MinStack{
        //俩系统栈
        public Stack<Integer> dataStack;
        public Stack<Integer> minStack;

        public MinStack(){
            dataStack = new Stack<>();
            minStack = new Stack<>();
        }

        //isEmpty
        public boolean isEmpty(){
            return dataStack.isEmpty();
        }

        //push
        public void push(int value){
            //data正常玩自己的
            dataStack.push(value);
            //关键在这,判断新来的value,和minStack的栈顶,啥情况
            if (minStack.isEmpty()) minStack.push(value);//第一个来的数,必然就是它最小了
            else if (value >= minStack.peek()) {
                value = minStack.peek();//重新赋值给value,然后加入min,别忘了哦
                minStack.push(value);
            }
            else minStack.push(value);//如果跳过上面那些if,说明更小的来了
        }

        //pop
        public int pop(){
            //没有了报错
            if (dataStack.isEmpty()) throw new RuntimeException("没得数!");
            //min要和data数量一致,范围一致,所以要先弹出一个
            minStack.pop();
            return dataStack.pop();
        }

        //peek
        public int peek(){
            //没有就报错
            if (dataStack.isEmpty()) throw new RuntimeException("没得数!");
            //有就看栈顶,与min无关
            return dataStack.peek();
        }

        //关键函数来了,getMin
        public int getMin(){
            //没有元素,报错
            if (minStack.isEmpty()) throw new RuntimeException("没得数!");
            //有的话,自然,就返回minStack的栈顶,与data无关
            return minStack.peek();
        }
    }
    public static void test2(){
        MinStack stack = new MinStack();

        stack.push(2);
        System.out.println("当前最小值:"+ stack.getMin());//2
        stack.push(3);
        System.out.println("当前最小值:"+ stack.getMin());//2
        stack.push(1);
        System.out.println("当前最小值:"+ stack.getMin());//1
        stack.push(4);
        System.out.println("当前最小值:"+ stack.getMin());//1
        stack.push(5);
        System.out.println("当前最小值:"+ stack.getMin());//1
        System.out.println("栈顶数据:"+ stack.peek());//5
        System.out.println(stack.isEmpty());
        System.out.println(stack.pop());//5
        System.out.println("当前最小值:"+ stack.getMin());//1
        System.out.println(stack.pop());//4
        System.out.println("当前最小值:"+ stack.getMin());//1
        System.out.println(stack.pop());//1
        System.out.println("当前最小值:"+ stack.getMin());//2
        System.out.println(stack.pop());//3
        System.out.println("当前最小值:"+ stack.getMin());//2
        System.out.println(stack.pop());//2
        System.out.println(stack.isEmpty());
    }

    public static void main(String[] args) {
//        test();
        test2();
    }

看看结果,很完美:

当前最小值:2
当前最小值:2
当前最小值:1
当前最小值:1
当前最小值:1
栈顶数据:5
false
5
当前最小值:1
4
当前最小值:1
1
当前最小值:2
3
当前最小值:2
2
true

总结

提示:重要经验:

1)最小栈,无非就是多了一个存最小值的栈,换成最大栈的话,估计也是很简单的
2)用底层的系统数据结构,实现新的的你想要的数据结构,这就是学习数据结构与算法的意义,这是大厂未来要招聘你进入优化算法和实现新的业务功能的本质。

举报

相关推荐

0 条评论