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

栈结构实战:从「有效括号」到「最小栈」,吃透栈的核心用法

目录

一、入门必刷:LeetCode 20. 有效的括号

题目描述

解题思路

代码实现(Java)

复杂度分析

二、进阶挑战:LeetCode 155. 最小栈

题目描述

解题思路

代码实现(Java)

复杂度分析

三、两道题的核心思想总结


栈,作为一种 “后进先出(LIFO)” 的数据结构,看似简单,却是算法题里的常客。今天,我们就通过两道经典题 ——「有效括号」和「最小栈」,把栈的核心思想和应用场景讲透,看完你就能直接上手写代码。


一、入门必刷:LeetCode 20. 有效的括号

这是一道几乎所有栈入门都会遇到的题目,也是面试中的高频题,非常适合理解栈的核心特性。

题目描述

给定一个只包括'('')''{''}''['']'的字符串s,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

解题思路

这道题的核心逻辑,完美契合了栈 “后进先出” 的特性:

  • 遇到左括号:直接压入栈中,等待后续匹配。
  • 遇到右括号:需要和最近的一个未匹配的左括号配对。而栈顶元素,正好就是最近的左括号。
  • 匹配失败的情况:
    1. 栈为空,却遇到了右括号(没有左括号可以匹配)。
    2. 栈顶的左括号类型和当前右括号不匹配。
  • 遍历结束后,栈必须为空(所有左括号都找到了对应的右括号)。

为了快速判断括号类型,我们可以用一个哈希表来存储 “右括号 → 左括号” 的映射。

代码实现(Java)

java

运行

public boolean isValid(String s) { // 定义右括号到左括号的映射,方便匹配 Map<Character, Character> map = new HashMap<>(); map.put(')', '('); map.put('}', '{'); map.put(']', '['); Deque<Character> stack = new LinkedList<>(); for (char c : s.toCharArray()) { // 如果是右括号 if (map.containsKey(c)) { // 栈为空,或栈顶元素不匹配,直接返回false if (stack.isEmpty() || stack.peek() != map.get(c)) { return false; } // 匹配成功,弹出栈顶元素 stack.pop(); } else { // 如果是左括号,直接入栈 stack.push(c); } } // 遍历结束,栈必须为空 return stack.isEmpty(); }

复杂度分析

  • 时间复杂度:O (n),其中 n 是字符串的长度,我们只需遍历一次字符串。
  • 空间复杂度:O (n),最坏情况下,所有字符都是左括号,需要将所有字符压入栈中。

二、进阶挑战:LeetCode 155. 最小栈

这道题是栈的经典扩展,它要求我们在实现常规栈功能的同时,支持在常数时间内获取栈中的最小元素。

题目描述

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

实现MinStack类:

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

解题思路

这道题的难点在于,如何在O(1)时间内获取最小值。如果每次都遍历栈来查找最小值,时间复杂度会退化为 O (n),无法满足题目要求。

最经典的解法是使用双栈

  1. 主栈(dataStack):用来正常存储所有元素,实现pushpoptop等常规操作。
  2. 辅助栈(minStack):用来存储 “当前栈中的最小值”。每次主栈压入一个新元素时,辅助栈也压入当前的最小值;每次主栈弹出元素时,辅助栈也同步弹出。

这样,getMin()方法只需要直接返回辅助栈的栈顶元素即可,时间复杂度为 O (1)。

代码实现(Java)

java

运行

class MinStack { // 主栈:存储所有元素 private Deque<Integer> dataStack; // 辅助栈:存储当前的最小值 private Deque<Integer> minStack; public MinStack() { dataStack = new LinkedList<>(); minStack = new LinkedList<>(); } public void push(int val) { dataStack.push(val); // 辅助栈为空,或新元素小于等于当前最小值,压入新元素 if (minStack.isEmpty() || val <= minStack.peek()) { minStack.push(val); } else { // 否则,重复压入当前最小值,保持两栈同步 minStack.push(minStack.peek()); } } public void pop() { // 两栈同步弹出 dataStack.pop(); minStack.pop(); } public int top() { return dataStack.peek(); } public int getMin() { // 直接返回辅助栈栈顶元素 return minStack.peek(); } }

复杂度分析

  • 时间复杂度:所有操作pushpoptopgetMin均为 O (1)。
  • 空间复杂度:O (n),我们使用了两个栈,在最坏情况下需要存储 2n 个元素。

三、两道题的核心思想总结

这两道题,从不同角度展现了栈的应用:

  • 有效括号:利用栈 “后进先出” 的特性,处理需要按顺序匹配的场景,比如括号匹配、HTML 标签闭合等。
  • 最小栈:利用 “双栈同步” 的思想,在保留常规栈功能的同时,扩展出了高效获取最小值的能力,这是一种非常经典的空间换时间的优化思路。
http://www.jsqmd.com/news/709182/

相关文章:

  • [特殊字符] 终极漫画阅读体验:Venera 开源阅读器完整指南!
  • 告别Electron!用Qt QWebEngine + QWebChannel 打造高性能桌面混合应用(附完整Demo)
  • EmojiOne彩色字体终极指南:5分钟打造跨平台表情统一体验
  • 别再只给Gerber了!与PCB工厂高效沟通:坐标文件和钻孔文件的正确打开方式
  • WarcraftHelper终极优化指南:2024年魔兽争霸III完全配置教程
  • GPEN处理儿童照片伦理规范建议:避免过度美化
  • 2026 内蒙古防静电地板与硫酸钙防静电地板本土厂家甄选参考 - 深度智识库
  • CompLLM:大语言模型长上下文处理技术解析
  • 多模态大语言模型推理能力提升方法DRIFT解析
  • 从Rancher Server到Node Agent:一张图看懂Rancher 2.8架构,搞懂它如何“遥控”你的K8s
  • PvZWidescreen终极指南:免费让《植物大战僵尸》完美适配宽屏显示器
  • florr.io新手必看:从Ant Egg到Mythic,一份超详细的生物掉落率速查表(附实战心得)
  • 清晰曝光与长效耐用兼得——2026四川招牌/灯箱制作优选服务商横评 - 深度智识库
  • 5大核心功能深度解析:英雄联盟智能助手如何提升你的游戏体验
  • 杭州手作冰淇淋加盟哪家可靠 - 速递信息
  • 具身智能中的传感器技术35——RGB-D相机0
  • LiteMall开源商城系统实战指南:Spring Boot + Vue + 微信小程序全栈深度解析
  • 明日方舟游戏资源库:如何一站式获取超过12000个高清游戏素材
  • WarcraftHelper魔兽争霸III插件:解决经典游戏现代化问题的终极指南
  • 免费OpenAI API接口实战:从原理到部署的完整指南
  • Vue3 + Element Plus + TypeScript:Promise<string>转换错误深度解析与...
  • 必备的Android智能充电控制:如何让你的手机电池寿命延长一倍
  • 如何免费打造你的终极漫画阅读体验?Venera 开源阅读器完整指南 [特殊字符]
  • UI Grounding技术:多模态模型在界面自动化中的应用
  • 拯救论文党:VSCode配置LaTeX Workshop插件全攻略(支持BibTeX引用与一键清理)
  • 2026年波兰华沙石材及石材机械展 Stone Poland - 中国组团单位- 新天国际会展 - 新天国际会展
  • 服务治理监控体系
  • 别再手动处理数据了!用MATLAB Simulink一键导入Fluent结果做二次仿真(附完整代码)
  • 手把手调试UICC CAT:使用APDU工具模拟终端与SIM卡的完整对话流程
  • 元宇宙资产公证员入门手册