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

O(1) 时间获取最小值的巧妙设计——力扣155.最小栈

力扣155.最小栈

在这里插入图片描述

【LeetCode 155】最小栈(Java 题解 + 三种实现方式详细对比)

一、题目描述

请你设计一个支持以下操作的栈(Stack):

  • push(int val):将元素压入栈。
  • pop():删除栈顶元素。
  • top():返回栈顶元素。
  • 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

三、题目分析

普通栈能在 O(1) 时间完成 push()pop()top() 操作。
getMin() 操作如果每次都线性扫描,复杂度将变为 O(n)。

为了在 O(1) 时间获取最小值,需要额外维护一个辅助结构

核心思想:

在每次压入或弹出时,同时维护当前最小值。


四、解法一:双栈法(推荐)

思路:

使用两个栈:

  • 一个普通栈 dataStack 存放所有元素;
  • 一个辅助栈 minStack 存放“每一步的最小值”。

规则:

  • 每次 push(val) 时:

    • val 压入 dataStack
    • Math.min(val, 当前最小值) 压入 minStack
  • 每次 pop() 时:

    • 两个栈同时弹出;
  • getMin() 时:

    • 返回 minStack 栈顶。

代码实现:

import java.util.Stack;class MinStack {private Stack<Integer> dataStack; // 数据栈private Stack<Integer> minStack;  // 最小值栈public MinStack() {dataStack = new Stack<>();minStack = new Stack<>();}public void push(int val) {dataStack.push(val);// 若 minStack 为空,则直接压入;否则压入两者中较小的值if (minStack.isEmpty()) {minStack.push(val);} else {minStack.push(Math.min(val, minStack.peek()));}}public void pop() {dataStack.pop();minStack.pop();}public int top() {return dataStack.peek();}public int getMin() {return minStack.peek();}
}

在这里插入图片描述

时间复杂度:

  • 所有操作均为 O(1)。

空间复杂度:

  • O(n),需要额外的 minStack。

五、解法二:单栈 + 辅助变量

思路:

只用一个栈和一个变量 min 保存当前最小值。

每次 push 时:

  • 如果新元素小于当前 min,先把旧的 min 压入栈,再更新 min

每次 pop 时:

  • 如果弹出的元素等于当前 min,说明最小值被弹出,需要恢复上一个最小值。

代码实现:

import java.util.Stack;class MinStack {private Stack<Integer> stack;private int min;public MinStack() {stack = new Stack<>();min = Integer.MAX_VALUE;}public void push(int val) {if (val <= min) {// 先保存旧的最小值stack.push(min);min = val;}stack.push(val);}public void pop() {if (stack.pop() == min) {// 恢复之前的最小值min = stack.pop();}}public int top() {return stack.peek();}public int getMin() {return min;}
}

在这里插入图片描述

优点:

  • 不需要额外栈;
  • 内存占用略小。

缺点:

  • 逻辑略微复杂;
  • 需要仔细处理 push 和 pop 的顺序。

六、解法三:链表节点法(扩展理解)

有时我们可以不使用 Stack 类,而是用自定义链表结构实现。

每个节点存储:

  • 当前值 val
  • 当前最小值 min
  • 下一个节点 next

代码实现:

class MinStack {private Node head;private class Node {int val;int min;Node next;Node(int val, int min, Node next) {this.val = val;this.min = min;this.next = next;}}public void push(int val) {if (head == null) {head = new Node(val, val, null);} else {head = new Node(val, Math.min(val, head.min), head);}}public void pop() {head = head.next;}public int top() {return head.val;}public int getMin() {return head.min;}
}

在这里插入图片描述

优点:

  • 不依赖 Stack;
  • getMin() 始终 O(1)。

缺点:

  • 不如前两种方法直观。

七、三种方法对比

方法思路额外空间代码复杂度推荐程度
双栈法dataStack + minStackO(n)简洁清晰★★★★★
单栈 + 辅助变量栈内保存旧最小值O(n)稍复杂★★★★☆
链表节点法每节点保存当前最小值O(n)不依赖 Stack★★★☆☆

八、复杂度分析

操作时间复杂度空间复杂度
push()O(1)O(1)
pop()O(1)O(1)
top()O(1)O(1)
getMin()O(1)O(1)

九、总结

最小栈设计的核心思想:

在每次操作时,维护当前“最小值”的状态,使得 getMin() 可以在 O(1) 时间内完成。

重点记忆:

  1. 双栈法是最直观的面试写法;
  2. 单栈 + 辅助变量是空间优化思路;
  3. 链表法体现了数据结构设计的灵活性。

十、参考链接

  • LeetCode 155. Min Stack 题目链接

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

相关文章:

  • 韩国网站建设wordpress安装博客步骤
  • dbpystream webapi: 一次clickhouse数据从系统盘迁至数据盘的尝试
  • 大数据-136 - ClickHouse 集群 表引擎详解 选型实战:TinyLog/Log/StripeLog/Memory/Merge
  • 高效的项目构建和优化之前端构建工具
  • 网站建设公司宣传文案如何通过cpa网站做推广
  • windows环境,设置git 默认提交信息
  • 电商平台网站建设合同宁波seo优化报价多少
  • 哪里找人做网站系统设计
  • 做一个网站需要多少钱大概费用商贸有限公司注销流程
  • OpenVLA-OFT+ 在真实世界 ALOHA 机器人任务中的应用
  • 网站调用字体四网合一网站建设
  • 网站优化包括整站优化吗公司管理体系
  • Spring—Springboot篇
  • 《拆解一封网络信:HTTP 报文详解》
  • wordpress仿站网桌子seo关键词
  • 如何判断服务器是否遭受攻击?
  • DGX A100服务器常见故障解析与维修攻略
  • 各品牌服务器IPMI配置实战经验分享
  • 海口自助建站知乎的网站建设和网站运营
  • 营销策略ppt聊城优化seo
  • 手表网站排行榜个人网站备案申请
  • [无人机sdk] MissionManager | WaypointMission | HotpointMission
  • UGUI源码剖析(16):实战——从零构建一个RadialSlider
  • 做网站要分几部分完成南京做网站公司哪家好
  • 软件测试和DevOps的关系
  • 【vllm】源码解读:DeepSeekV2 DP Rank 专家加载与分配机制
  • YOLOv5 代码深度解析总结
  • 钓鱼网站的制作教程全球网站排行榜
  • 解决 Codex 在 WSL/SSH/VSCODE 登录时报 “Token exchange failed: 403 Forbidden” 问题
  • JS逆向——encrypt-labs实现爆破登录