【栈】包含min最小值的栈 (Java)

简单双栈实现

增加一个minStack 用以维持 此时的最小值,每次push进栈的同时,将将此时的最小值push到minStack中;同时出栈也将minStack 也出栈。


/**
 * 双栈实现
 * 空间复杂度 O(n)
 */

import java.util.Stack;

public class Solution {

    Stack<Integer> minStack = new Stack<>();
    Stack<Integer> stack = new Stack<>();

    public void push(int node){
        stack.push(node);
        if(minStack.isEmpty())
            minStack.push(node);
        else{
            minStack.push(Math.min(minStack.peek(), node));
        }
    }

    public void pop(){
        if(stack.isEmpty())
            return;
        stack.pop();
        minStack.pop();
    }

    public int top(){
        if(stack.isEmpty())
            return -1;
        return stack.peek();
    }

    public int min(){
        if(stack.isEmpty())
            return -1;
        return minStack.peek();
    }
}

压缩还原法(不用冗余的栈)

我们发现其实最小值min它本身就是一种冗余信息。为什么呢?因为每个元素在数值上都包含了min值,举个例子,假设入栈序列为:4、5、6、3、2、1,那么各轮次对应的min值就是:4、4、4、3、2、1,发现有:
4=4+0,5=4+1,6=4+2,3=4+(-1),2=3+(-1),1=2+(-1);各个元素在数值上已经包含了在它之前的最小值的值;
那么,我们是不是只要在数据栈中存储0、1、2、-1、-1、-1,然后再使用一个辅助变量min=1就可以了呢?
这样,根据单个辅助变量和栈中存储的值就能够推理出top值和min值了,具体规则如下:

入栈:

压缩:将要入栈的元素value减去当前最小值min,得到一个差值diff,只存储该差值;
更新:如果入栈的元素value比当前最小值min小,则要更新最小值:min=value;
初始:第一次入栈比较特殊,因为此时的min变量并没有值,所以令:min=value;

出栈:

更新:如果栈中存储的差值diff是负数,说明出栈的元素是当前最小值min,需要把min值更新为上一个最小值min = min - diff,否则,出栈的元素不是最小值,则不对min变量做任何操作;
还原:如果栈中存储的差值diff是正数,说明 top = min + diff,否则,说明top元素本身是最小值 top = min;


/**
 * 压缩还原法
 * 空间复杂度 O(1)
 */

import java.util.Stack;

public class Solution2 {

    Stack<Integer> stack = new Stack<Integer>();
    int min;

    public void push(int node){
        if(stack.isEmpty()){
            min = node;
            stack.push(node - min);
        }else{
            int diff = node - min;
            stack.push(diff);
            if(diff < 0)
                min = node;
        }
    }

    public void pop(){
        if(stack.isEmpty())
            return;
        int diff = stack.pop();
        if(diff < 0){
            min = min - diff;
        }
    }

    public int top(){
        if(stack.isEmpty())
            return -1;
        int diff = stack.peek();
        if(diff < 0){
            return min;
        }
        return min + diff;
    }

    public int min(){
        if(stack.isEmpty())
            return -1;
        return min;
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值