zoukankan      html  css  js  c++  java
  • 最小栈的实现与优化

    最小栈

    实现一个最小栈,一步一步优化,从额外空间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<Integer> data = new Stack<Integer>();
    	private Stack<Integer> minValue = new Stack<Integer>();
    
    	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
    2 2 0 2
    1 1 -1 1
    3 1 2 1
    4 1 3 1
    -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<Integer> diff = new Stack<Integer>();
    	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;
    	}
    }
    

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

  • 相关阅读:
    vue-cli脚手架工具构建&初始化vue项目
    2020/05/17 Github加速-DNS配置
    同时将本地git仓库提交到gitee和github
    git远程仓库在本地看不到&push 到远程仓库失败的解决方案
    stylus的使用-变量和函数
    webpack使用4-HRM热替换&SourceMap&解析es语法
    webpack使用3-plugin插件的使用
    webpack使用2-常用的几个loader的使用
    webpack基本使用
    spring框架里面的注入?
  • 原文地址:https://www.cnblogs.com/byrhuangqiang/p/4682354.html
Copyright © 2011-2022 走看看