千家信息网

最小栈的实现与优化

发表于:2025-01-22 作者:千家信息网编辑
千家信息网最后更新 2025年01月22日,最小栈实现一个最小栈,一步一步优化,从额外空间O(N) 到O(1) 。面试官看重代码逻辑。push,pop,top,getMin都是O(1)时间。1 用一个最小栈来存储最小值1.1要点:2个栈,dat
千家信息网最后更新 2025年01月22日最小栈的实现与优化

最小栈

实现一个最小栈,一步一步优化,从额外空间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).

public class MinStack1 {    private Stack data = new Stack();    private Stack minValue = new Stack();    public void push(int x) {        data.push(x);        if (minValue.isEmpty() || x <= minValue.peek())            minValue.push(x);    }    public void pop() {        int value = data.pop();        if (value == minValue.peek())            minValue.pop();    }    public int top() {        return data.peek();    }    public int getMin() {        return minValue.peek();    }}

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的特殊处理。

public class MinStack3 {    private Stack diff = new Stack();    private int minValue;    public void push(int x) {        if (diff.isEmpty()) {            minValue = x;            diff.push(0);        } else {            int compare = x - minValue;            diff.push(compare);            minValue = compare < 0 ? x : minValue;        }    }    public void pop() {        int top = diff.peek();        minValue = top < 0 ? (minValue - top) : minValue;        diff.pop();    }    public int top() {        int top = diff.peek();        return top > 0 ? top + minValue : minValue;    }    public int getMin() {        return minValue;    }}

新航道雅思

0