【最小栈】最小栈的实现与优化

最小栈

实现一个最小栈,一步一步优化,从额外空间O(N) 到O(1) 。push,pop,top,getMin都是O(1)时间。

1 用一个最小栈来存储最小值

1.1要点:

  • 2个栈,data用来存储数据,minValue用来存储最小值。
  • push时,data直接push数据;minValue直接放入当前最小的值。(对于minValue有一个优化,当push的数据比当前最小值大的时候,我们可以不对minValue进行最小值的插入;如果小于或者等于最小值,就需要把最新的最小值push入栈minValue。
  • pop时,data直接pop出数据;同时,更新minValue,更新的策略是与push中的优化对应的策略——pop出的数,如果==当前的最小值,就需要把minValue进行pop一次。
  • getMin:直接返回栈minValue 的 top元素即可。
  • top: 直接返回栈data的top元素即可。

1.2 复杂度和代码

空间消耗O(N),如何优化到O(1).

class MinStack1 {
     stack<int>data ;
     stack<int>minValue;
     void push(int x) {
        data.push(x);
        if (minValue.empty() || x <= minValue.top())
            minValue.push(x);
    }

     void pop() {
        int value = data.top();data.pop();
        if (value == minValue.top())
            minValue.pop();
    }

   int top() {
        return data.top();
    }

     int getMin() {
        return minValue.top();
    }
};

2 优化空间复杂度到O(1)

如何只用一个栈实现最小栈的实现?

  • 栈不能够只存储原始数据,应该存储差值(类似于通信原理里面的差值编码)。
  • 用一个变量来计算栈的最小值。
  • 用简单的示例来探索思路。

2.1 图

入栈顺序:2,1,3,4,-2,0,-2
diff栈的计算 = data - min

出栈的data最小值 diff栈最小值min
22 02
11 -11
31 21
41 31
-2-2 -3-2
0-2 2-2
-2-2 0-2

top : 如何根据diff栈来恢复栈顶top的元素?
push : 如何更新min最小值?
pop : 如何维护min的最小值?

2.2 代码

注意:第一次入栈diff的特殊处理。

class MinStack3 {
    stack<int>diff;
    int minValue;
	
    void push(int x) {
        if (diff.empty()) {
            minValue = x;
            diff.push(0);
        } else {
            int compare = x - minValue;
            diff.push(compare);
            minValue = compare < 0 ? x : minValue;
        }
    }

    void pop() {
        int top = diff.top();
        minValue = top < 0 ? (minValue - top) : minValue;
        diff.pop();
    }

    int top() {
        int top = diff.top();diff.pop();
        return top > 0 ? top + minValue : minValue;
    }

    int getMin() {
        return minValue;
    }
};

 

致命缺点:由于存储差值,无法解决溢出的可能问题。

转自:https://www.cnblogs.com/byrhuangqiang/p/4682354.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值