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

LeetCode 热题 100 155. 最小栈

LeetCode 热题 100 | 155. 最小栈

大家好!今天我们来解决一道经典的算法题——最小栈。这道题要求我们设计一个支持 pushpoptop 操作,并能在常数时间内检索到最小元素的栈。下面我将详细讲解解题思路,并附上Python代码实现。


一、问题描述

设计一个支持以下操作的栈:

  1. MinStack():初始化栈对象。
  2. void push(int val):将元素 val 推入栈。
  3. void pop():删除栈顶部的元素。
  4. int top():获取栈顶部的元素。
  5. int getMin():获取栈中的最小元素。

要求所有操作的时间复杂度为 O(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.

二、解题思路

核心思想

为了在常数时间内获取栈中的最小元素,我们需要在每次操作时维护当前栈的最小值。具体方法如下:

  1. 辅助栈
    • 使用两个栈:一个主栈 stack 用于存储所有元素,一个辅助栈 minStack 用于存储当前栈的最小值。
    • 每次 push 时,将元素压入主栈,并将当前最小值压入辅助栈。
    • 每次 pop 时,同时从主栈和辅助栈中弹出元素。
    • getMin 操作直接返回辅助栈的栈顶元素。

代码实现

class MinStack:def __init__(self):# 初始化主栈和辅助栈self.stack = []self.minStack = []def push(self, val: int) -> None:# 将元素压入主栈self.stack.append(val)# 将当前最小值压入辅助栈if not self.minStack or val < self.minStack[-1]:self.minStack.append(val)else:self.minStack.append(self.minStack[-1])def pop(self) -> None:# 从主栈和辅助栈中弹出元素self.stack.pop()self.minStack.pop()def top(self) -> int:# 返回主栈的栈顶元素return self.stack[-1]def getMin(self) -> int:# 返回辅助栈的栈顶元素,即当前栈的最小值return self.minStack[-1]

代码解析

  1. 初始化

    • __init__ 方法中,初始化两个栈:stackminStack
  2. push 操作

    • 将元素压入主栈 stack
    • 如果辅助栈为空或新元素小于辅助栈的栈顶元素,则将新元素压入辅助栈;否则,将辅助栈的栈顶元素再次压入辅助栈。
  3. pop 操作

    • 同时从主栈和辅助栈中弹出元素。
  4. top 操作

    • 返回主栈的栈顶元素。
  5. getMin 操作

    • 返回辅助栈的栈顶元素,即当前栈的最小值。

复杂度分析

  • 时间复杂度:所有操作的时间复杂度均为 O(1)。
  • 空间复杂度:O(n),其中 n 是栈中元素的数量。辅助栈 minStack 的大小与主栈相同。

示例运行

示例1
# 创建 MinStack 对象
minStack = MinStack()
# 执行操作
minStack.push(-2)
minStack.push(0)
minStack.push(-3)
print(minStack.getMin())  # 输出 -3
minStack.pop()
print(minStack.top())     # 输出 0
print(minStack.getMin())  # 输出 -2

输出

-3
0
-2

总结

通过使用辅助栈,我们可以在常数时间内实现 pushpoptopgetMin 操作。这种方法不仅简单高效,而且易于理解和实现。希望这篇题解对大家有所帮助,如果有任何问题,欢迎在评论区留言讨论!

关注我,获取更多算法题解和编程技巧!

相关文章:

  • unix/linux source 命令,其高级使用
  • 历史数据分析——广州港
  • C#里与嵌入式系统W5500网络通讯(3)
  • Java补充(Java8新特性)(和IO都很重要)
  • 零基础安装 Python 教程:从下载到环境配置一步到位(支持 VSCode 和 PyCharm)与常用操作系统操作指南
  • 【Go-6】数据结构与集合
  • 【Java】JDK 命令行工具
  • WIN11+VSCODE搭建的c/c++环境调试报错解决
  • 数据要素×AI:高质量数据集如何成为智能时代的“新石油“
  • Python 中 dpkt 库的详细使用指南(强大的 Python 数据包解析库)
  • git 如何解决分支合并冲突(VS code可视化解决+gitLab网页解决)
  • 238除自身以外数组的乘积
  • Go 语言 select 语句详解
  • 【STM32开发板】接口部分
  • Oracle正则表达式学习
  • LeetCode 39.组合总和:回溯法与剪枝优化的完美结合
  • Go语言常见接口设计技巧-《Go语言实战指南》
  • 题单:最大公约数(辗转相除法)
  • 数据结构之ArrayList
  • 【C/C++】面试基础题目收集
  • 临安区建设局网站/链爱交易平台
  • 政府蒙古文网站建设汇报材料/公司业务推广
  • 网站的后台怎么做/成人职业技能培训班
  • 阿里云做外贸网站/长沙网站推广seo
  • 手机咋建网站/seo托管
  • 网站和虚拟服务器/营销网站建设免费