155.最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack()初始化堆栈对象。void push(int val)将元素val推入堆栈。void pop()删除堆栈顶部的元素。int top()获取堆栈顶部的元素。int getMin()获取堆栈中的最小元素。
你必须实现一个时间复杂度为 O(1) 的栈,而且还支持 getMin 操作。
示例:
1 | 输入: |
解题思路
这是一道经典的设计题,考察对栈的理解和最小值的维护。
核心思想
- 使用两个栈:一个存储数据,一个存储最小值
- 每次push时,同时更新最小值栈
- 每次pop时,同时更新最小值栈
方法一:双栈法(推荐)
时间复杂度 O(1)、空间复杂度 O(n)
1 | /** |
方法二:优化版本(存储差值)
1 | var MinStack = function() { |
方法三:使用对象存储
1 | var MinStack = function() { |
方法四:单栈法(存储元组)
1 | var MinStack = function() { |
解题要点
双栈法:
- 主栈存储所有元素
- 最小栈存储当前最小值
- 每次push时更新最小栈
- 每次pop时检查是否需要更新最小栈
时间复杂度:
- 所有操作都是O(1)
- 空间复杂度O(n)
边界处理:
- 空栈的情况
- 重复最小值的情况
面试要点
- 高频考点:这道题是面试中的高频设计题
- 栈操作:考察对栈的基本操作的理解
- 最小值维护:考察如何高效维护最小值
- 时间复杂度:要求O(1)的操作复杂度
相关题目
- 232.用栈实现队列 - 栈和队列的转换
- 225.用队列实现栈 - 队列实现栈
- 716.最大栈 - 类似题目,维护最大值
扩展思考
为什么使用双栈法?
- 主栈维护正常的栈操作
- 最小栈维护当前的最小值
- 两个栈同步操作,保证O(1)复杂度
时间复杂度分析
- push操作:O(1)
- pop操作:O(1)
- top操作:O(1)
- getMin操作:O(1)
空间复杂度优化
- 双栈法:O(n)
- 差值法:O(n)但常数更小
- 对象法:O(n)
实际应用
- 股票价格的最小值跟踪
- 温度记录的最低温度
- 游戏中的最低分数
变种问题
- 支持getMax操作
- 支持getMin和getMax
- 支持范围查询
最后更新: 2021-09-21