剑指offer-20、包含min函数的栈

题⽬描述

定义栈的数据结构,请在该类型中实现⼀个能够得到栈中所含最⼩元素的min 函数(时间复杂度为O(1) )。

此栈包含的⽅法有:

  • push(value) :将value 压⼊栈中
  • pop() :弹出栈顶元素
  • top() :获取栈顶元素
  • min() :获取栈中最⼩元素

思路及解答

双栈法(推荐,实现简单)

使用两个栈:

  1. 主栈:存储所有元素
  2. 辅助栈:存储当前主栈中的最小值

push ⼀个元素的时候,都需要push 进datas stack ,但是push 进⼊mins stack 需要满⾜条件:当前的mins stack 是空的,直接放⼊。或者当前的mins stack 的栈顶元素⼤于或者等于push 进来的值。

pop ⼀个元素的时候,如果栈为空则什么都不操作,如果栈不为空,则判断datas 的第⼀个元素是否和mins 的第⼀个元素相等。如果相等的话那么就需要将mins 和datas pop 出去第⼀个元素,否则只需要将datas 的第⼀个元素 pop 出去即可。

java 复制代码
public class Solution {
	private Stack<Integer> datas = new Stack<>();
	private Stack<Integer> mins = new Stack<>();

	/​**​
     * 将元素压入栈中
     * @param value 要压入的值
     */
	public void push(int node) {
		datas.push(node);
		// 如果辅助栈为空,或新值<=当前最小值,压入辅助栈
		if (mins.isEmpty()) {
			mins.push(node);
		} else {
			int min = mins.peek();
			if (node <= min) {
				mins.push(node);
			}
		}
	}
	
	public void pop() {
		if (datas.isEmpty()) {
			return;
		} else {
			int value = datas.peek();
			if (value == mins.peek()) {
				mins.pop();
			}
			datas.pop();
		}
	}
	
	public int top() {
		if(datas.isEmpty()){
			return -1;
		}
		return datas.peek();
	}
	
	public int min() {
		if(mins.isEmpty()){
			return -1;
		}
		return mins.peek();
	}
}
  • 时间复杂度: O(1)
  • 空间复杂度: O(n) ,借助了辅助栈。

差值法

使用一个栈和一个变量minValue

  1. 栈存储差值:存储元素与当前最小值的差值
  2. 更新最小值:当遇到更小值时,先存储当前差值(负值),再更新最小值
  3. 恢复前值pop时如果发现差值为负,说明此处发生过最小值更新,需要恢复前一个最小值
java 复制代码
public class Solution {
    private Stack<Long> stack = new Stack<>();; // 存储差值的栈
    private long minValue; // 当前最小值

    public void push(int value) {
        if (stack.isEmpty()) {
            minValue = value;
            stack.push(0L); // 差值为0
        } else {
            long diff = (long)value - minValue;
            stack.push(diff);
            // 如果差值为负,说明value是新的最小值
            if (diff < 0) {
                minValue = value;
            }
        }
    }

    public void pop() {
        if (stack.isEmpty()) {
            return;
        }
        long diff = stack.pop();
        // 如果差值为负,说明此处更新过最小值,需要恢复前一个最小值
        if (diff < 0) {
            minValue = minValue - diff;
        }
    }

    public int top() {
        if (stack.isEmpty()) {
           return;
        }
        long diff = stack.peek();
        // 如果差值为负,说明当前栈顶就是最小值
        if (diff < 0) {
            return (int)minValue;
        } else {
            return (int)(minValue + diff);
        }
    }

    public int min() {
        if (stack.isEmpty()) {
           return;
        }
        return (int)minValue;
    }
}
  • 时间复杂度:所有操作仍为O(1)
  • 空间复杂度:O(1)额外空间(仅一个变量),但栈存储的是差值而非原始值

需要考虑整数溢出问题(使用long存储差值)

相关推荐
阿里巴巴P8高级架构师3 分钟前
从0到1:用 Spring Boot 4 + Java 21 打造一个智能AI面试官平台
java·后端
stevenzqzq5 分钟前
trace和Get thread dump的区别
java·android studio·断点
桦说编程6 分钟前
并发编程踩坑实录:这些原则,帮你少走80%的弯路
java·后端·性能优化
程序猿零零漆6 分钟前
Spring之旅 - 记录学习 Spring 框架的过程和经验(十三)SpringMVC快速入门、请求处理
java·学习·spring
BHXDML6 分钟前
JVM 深度理解 —— 程序的底层运行逻辑
java·开发语言·jvm
tkevinjd8 分钟前
net1(Java中的网络编程、TCP的三次握手与四次挥手)
java
码头整点薯条9 分钟前
基于Java实现的简易规则引擎(日常开发难点记录)
java·后端
J2虾虾17 分钟前
Java使用的可以使用的脚本执行引擎
java·开发语言·脚本执行
老马识途2.022 分钟前
java处理接口返回的json数据步骤 包括重试处理,异常抛出,日志打印,注意事项
java·开发语言
2***d88523 分钟前
Spring Boot中的404错误:原因、影响及处理策略
java·spring boot·后端