剑指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存储差值)

相关推荐
短剑重铸之日5 小时前
《ShardingSphere解读》07 读写分离:如何集成分库分表+数据库主从架构?
java·数据库·后端·架构·shardingsphere·分库分表
知我Deja_Vu5 小时前
【避坑指南】ConcurrentHashMap 并发计数优化实战
java·开发语言·python
daidaidaiyu6 小时前
Spring IOC 源码学习 事务相关的 BeanDefinition 解析过程 (XML)
java·spring
鬼蛟7 小时前
Spring————事务
android·java·spring
西门吹-禅8 小时前
【sap fiori cds up error】
java·服务器·sap cap cds
敲代码的嘎仔8 小时前
Java后端面试——SSM框架面试题
java·面试·职场和发展·mybatis·ssm·springboot·八股
大傻^8 小时前
Spring AI Alibaba RAG实战:基于向量存储的检索增强生成
java·人工智能·spring
大傻^8 小时前
Spring AI Alibaba 快速入门:基于通义千问的AI应用开发环境搭建
java·人工智能·后端·spring·springai·springaialibaba
伯恩bourne8 小时前
Google Guava:Java 核心工具库的卓越之选
java·开发语言·guava
小王不爱笑1329 小时前
Spring 基础核心
java