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

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 操作。这种方法不仅简单高效,而且易于理解和实现。希望这篇题解对大家有所帮助,如果有任何问题,欢迎在评论区留言讨论!

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

http://www.xdnf.cn/news/10407.html

相关文章:

  • Broker、Proxy、Agent的区别
  • 用提示词写程序(3),VSCODE+Claude3.5+deepseek开发edge扩展插件V2
  • C++ 开发,将数值转换为字符串问题,不能直接拼接引号
  • HarmonyOS NEXT~鸿蒙开发工具CodeGenie:AI驱动的开发效率革命
  • 火语言UI组件--文件对话框
  • chrome.runtime.sendMessage 和 new FormData()
  • SRD-12VDC-SL-C 继电器‌接线图解
  • golang -- slice 底层逻辑
  • 针对 Harmony-Cordova 性能优化,涵盖原生插件开发、线程管理和资源加载等关键场景
  • 某航后缀混淆逆向与顶像风控分析
  • 第十五章 访问控制
  • DelphiXe12创建DataSnap REST Application
  • 深度学习篇---face-recognition的优劣点
  • 计算机视觉---YOLOv5
  • 多模态大语言模型arxiv论文略读(102)
  • HackMyVM-Jabita
  • AI精准挖掘SEO关键词策略
  • Spring Security安全实践指南
  • 《操作系统真相还原》——进入内核
  • NodeJS全栈开发面试题讲解——P11消息队列(MQ)
  • 杨校老师竞赛课之GESP一级C++[2024-12]真题及题解
  • git 学习
  • Leetcode 3567. Minimum Absolute Difference in Sliding Submatrix
  • Spring Boot 全局配置文件优先级
  • 基于springboot的宠物领养系统
  • 本振相参解析(1)2025.6.1
  • 【华为云Astro】从OBS CSV文件获取配置指南
  • 语音数据处理:ueng 与 ong 的统一表示方案
  • Python数据类型详解:从字符串到布尔值,一网打尽
  • Vue-2-前端框架Vue基础入门之二