当前位置: 首页 > news >正文

栈题解——最小栈【LeetCode】

155. 最小栈

题目描述

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

  • MinStack() 初始化堆栈对象。
  • void push(int val) 将元素val推入堆栈。
  • void pop() 删除堆栈顶部的元素。
  • int top() 获取堆栈顶部的元素。
  • int getMin() 获取堆栈中的最小元素。

示例 1:

输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]输出:
[null,null,null,null,-3,null,0,-2]解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

提示:

  • -231 <= val <= 231 - 1
  • poptop 和 getMin 操作总是在 非空栈 上调用
  • pushpoptop, and getMin最多被调用 3 * 104 次

我们来分析这段实现 支持常数时间获取最小值的栈(MinStack) 的代码,从三个角度出发:


一、算法逻辑讲解(思路分步)

整体目标:
设计一个栈结构,要求支持四种操作:

  • push(val): 入栈元素 val;
  • pop(): 弹出栈顶元素;
  • top(): 获取栈顶元素;
  • getMin(): 获取当前栈中的最小值。
初始化
self.st = [(0, inf)]
  • 初始化时栈中放入一个哨兵 (0, inf)
    • 0 是占位数,实际不用,避免栈为空的边界判断。
    • inf 是正无穷,表示最小值的初始值永远不会被使用。
    • 用一个 二元组 表示栈元素:(val, 当前最小值),这样可以实现 O(1) 取最小值。
push(val)
self.st.append((val, min(self.st[-1][1], val)))
  • 每次压入新值 val同时记录当前栈中的最小值
    • self.st[-1][1] 是栈顶记录的“之前”的最小值;
    • min(...) 是“当前”与“之前”最小值取更小的那个;
    • 所以每个栈元素都带着“当前入栈时的最小值”。
pop()
self.st.pop()
  • 弹出栈顶元素,直接 pop 即可;
  • 由于最小值是绑定在元素上的,所以不会丢失信息。
top()
return self.st[-1][0]
  • 返回栈顶的元素值。
getMin()
return self.st[-1][1]
  • 返回栈顶记录的当前最小值。

二、算法核心点(关键技巧)

✅ 核心技巧:栈中每个元素都附带一个当前最小值

这是本算法的关键优化 ——

  • 在入栈的时候,提前计算好每个状态下的最小值并存储下来;
  • 这样在 getMin() 的时候就能做到 O(1) 时间复杂度;
  • 所以不是每次动态去遍历栈找最小值,而是把“最小值随时间演变的轨迹”记录在每个节点中。

这种结构也被称为 “辅助栈思想” 的一种优化实现(实际上这里是“主栈 + 最小值绑定”)。

class MinStack:def __init__(self):# 这里的 0 写成任意数都可以,反正用不到self.st = [(0, inf)]  # 栈底哨兵def push(self, val: int) -> None:self.st.append((val, min(self.st[-1][1], val)))def pop(self) -> None:self.st.pop()def top(self) -> int:return self.st[-1][0]def getMin(self) -> int:return self.st[-1][1]

三、复杂度分析

时间复杂度(所有操作):
  • push: O(1)
  • pop: O(1)
  • top: O(1)
  • getMin: O(1)

因为每个操作都只涉及栈顶元素的访问或更新,无需遍历。

空间复杂度:
  • O(n),其中 n 是入栈的元素个数。
  • 每个元素都存储了一个 (val, 当前最小值) 的二元组,因此是线性空间。

总结

维度

说明

✅ 思路逻辑

每个入栈元素都记录当前最小值

✅ 核心技巧

元素与当前最小值打包记录,空间换时间

✅ 时间复杂度

所有操作均为 O(1)

✅ 空间复杂度

O(n),每个入栈值都额外记录一个最小值

如需我用图示说明这段栈在操作过程中的状态变化,也可以继续补充!

http://www.dtcms.com/a/276605.html

相关文章:

  • 学历一般,基础一般还有必要刷算法题吗
  • 一种Φ325海底管道机械三通结构设计cad【1张】三维图+设计说明书
  • python学习笔记【1】对字符串的处理
  • 网络安全day1-2笔记
  • kettle从入门到精通 第101课 ETL之kettle DolphinScheduler调度kettle
  • RAG进阶之术:用“父子Chunk”策略破解复杂查询的“上下文迷局”
  • Win11怎样进入WinRE恢复环境
  • 并发--Callable vs Runnable
  • 深入理解 Boost.Asio 中的异步核心 boost::asio::io_context
  • AI智能体|扣子(Coze)搭建【裸眼3D著名故事动画视频】工作流
  • NOIP普及组|2005T1淘淘摘苹果
  • 常用控件QWidget
  • 部署Harbor私有仓库
  • 第五章 RAG知识库进阶
  • Java项目2——增强版飞机大战游戏
  • Linux:信号
  • Redis持久化机制:RDB和AOF
  • 【面试八股文】2025最新软件测试面试
  • 多模态数据解压-Parquet
  • 【数据结构初阶】--顺序表(三)
  • 咨询导览,AI发展趋势
  • 三维点云Transformer局部感受野构建:理论、方法与挑战
  • 【图像处理基石】如何入门大规模三维重建?
  • 宁德时代2025年社招入职Verify测评语言理解数字推理考点及SHL测评真题整理
  • Augmented Nested Arrays With Enhanced DOF and Reduced Mutual Coupling
  • C++面试问题集锦
  • Linux系统编程——目录 IO
  • C++ 算法题常用函数大全
  • 独立开发第二周:构建、执行、规划
  • 数智管理学(三十二)