力扣-栈-剑指 Offer 30. 包含min函数的栈(peek与pop、Integer.equals()与“==”、数组实现栈)

剑指 Offer 30. 包含min函数的栈

在这里插入图片描述

题解1-双栈

思路

用一个主栈以及一个辅助栈来实现这个功能,主栈负责主要的pop,push,辅助栈用来记录min。
其中:

  • push: 如果min栈为空,或压入的元素大于min栈的栈顶元素,则也将x压入min栈,注意这里需要用大于等于号,因为如果只是大于号,连续压入两个相同的最小值,再弹出一个最小值就会出错
  • pop:如果主栈pop出的元素与min栈的栈顶元素相同,则min也pop
  • top:获取主栈的栈顶元素
  • min:获取min栈的栈顶元素

代码

class MinStack {
	Stack<Integer> res;
	Stack<Integer> min;
    /** initialize your data structure here. */
    public MinStack() {
    	res=new Stack<Integer>();
    	min=new Stack<Integer>();
    }
    
    public void push(int x) {
    	res.push(x);
    	if(min.isEmpty()||min.peek()>=x)
        //如果不加等号的话,连续输入压入两个相同的最小值再弹出一个后,min栈中就没有这个最小值了
    		min.push(x);
    }
    		
    
    public void pop() {
    	if(res.pop().equals(min.peek()))
        //这里用“==”就会出错!!!
    		min.pop();
    }
    
    public int top() {
    	return res.peek();
    }
    
    public int min() {
    	return min.peek();
    }
}

知识点

peek与poop
  • Stack.peek() 返回栈顶元素。
  • Stack.pop() 返回栈顶元素,并在栈中删除它。
Integer.equals()与“==”

注意这里的代码的pop()处如果用"=="取代equals就会出错,这是因为:

  1. “==”两边都是包装类型时,会直接比较引用地址
  2. JAVA的Integer有IntegerCache,他会缓存[-128~127]之间的对象,也就是说如果创建的新对象的值在[-128~128]时,会检查是否有已存在的[-128~127],如果有就直接调用,否则才会产生新对象
  3. 也就是说,如果连续新建两个相同值的Integer,如果值的大小在[-128~127],他们两个用"=="就是相等的,如果在这个范围之外,他们就不是同一个地址,就是不同的。
    关于“==”与equals的区别,具体请看这个博主的文章:

https://www.cnblogs.com/mrhgw/p/10449391.html

题解2-单栈

思路

这里的思路就是只用一个栈,而最小值的获取方式为:

  • 每当想要压入的x值小于当前的min值时,就将当前的min值压入栈,表示这个位置以下的所有值的最小值。然后再在上面压入当前的x,并把x设为当前的新的min值。
  • 每当弹出的值等于当前的min值时,再弹出当前min值下一个的值,这个值也就是之前压进去的这个位置以下的所有值的最小值。
  • 其实就是多用了一些空间来存放了多个"从这个位置往下的最小值"

代码

class MinStack {
    Stack<Integer> stack;
    int min;
    /** initialize your data structure here. */
    public MinStack() {
        this.stack = new Stack<>();
    }
    public void push(int x) {
        if(stack.isEmpty()) {
            min = x;
        }
        if(x <= min){
        //压入上一个最小值
            stack.push(min);
            min = x;
        }
        stack.push(x);
    }
    
    public void pop() {
        if(min == stack.pop()){
        //读取上一个最小值
            min = stack.pop();
        }
    }
    
    public int top() {
        return stack.peek();
    }

    public int min() {
        return min;
    }
}

题解3-数组栈

思路

用数组自己实现栈

  • pop --> stack[top–]
  • push --> stack[++top]
代码
class MinStack {
    int[ ] stack;
    int min;
    int top;
    /** initialize your data structure here. */
    public MinStack() {
    	top=-1;
        this.stack = new int[40000];
        //最坏情况是不断压入更小的值20000次,此时栈需要40000位
    }
    public void push(int x) {
        if(top==-1) {
        	//栈为空
            min = x;
        }
        if(x <= min){
            stack[++top]=min;
            min = x;
        }
        stack[++top]=x;
    }
    
    public void pop() {
        if(min == stack[top--]){
            min = stack[top--];
        }
    }
    
    public int top() {
        return stack[top];
    }

    public int min() {
        return min;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值