【Java实习面试算法冲刺】栈、队列与单调栈 第5类题型栈、队列与单调栈为什么这一类题你总感觉概念都懂做题时却分不清该上哪个结构很多同学看到栈、队列、单调栈这类题时第一反应都是“概念我知道”。问题在于真正到了面试现场难点从来不是背定义而是你能不能把题意瞬间映射到正确的数据结构。这类题最容易暴露出几种问题你知道栈是后进先出但遇到括号匹配还是没第一时间反应过来。你会写Deque但push/pop和offer/poll一紧张就容易混。你记住了单调栈“递减 / 递增”的表述却没理解为什么很多题栈里要存下标。如果你现在处在“模板知道一点但题面一拐弯就发虚”的阶段这一类题非常值得单独梳理。读完这篇你至少要把 3 件事练熟先判断该用栈、队列还是单调栈理解单调栈里为什么经常保存下标能在面试里解释“当前元素到底在帮谁结算答案”。文章目录第5类题型栈、队列与单调栈1. 核心知识点动画辅助理解当前元素在帮谁结算答案2. 这类题在面试里考什么3. 高频题清单4. 这类题最容易犯的 3 个错误5. 代表题精讲 1题目思路Java 代码复杂度边界提醒如果这是面试现场你可以这样说6. 代表题精讲 2题目思路Java 代码复杂度边界提醒如果这是面试现场你可以这样说7. 其余题模板与关键片段[232. 用栈实现队列](https://leetcode.cn/problems/implement-queue-using-stacks/)[155. 最小栈](https://leetcode.cn/problems/min-stack/)8. 这三类结构怎么快速区分9. 错题本记录方式10. 面试前 3 分钟速记11. 最后总结不要只背结构定义要知道当前元素在做什么1. 核心知识点这一类题其实是三个模型栈后进先出常见于括号匹配、路径回退。队列先进先出常见于层序遍历、广度优先。单调栈维护“还没找到答案的元素”常见于“下一个更大元素”。Java 刷题里推荐统一使用ArrayDequeDequeIntegerstacknewArrayDeque();stack.push(x);stack.pop();stack.peek();DequeIntegerqueuenewArrayDeque();queue.offer(x);queue.poll();queue.peek();Stack类是老 API实战里一般不优先用。单调栈的核心理解是栈里存的往往不是值本身而是下标因为你最终要更新的是某个位置的答案。动画辅助理解当前元素在帮谁结算答案这一类题最适合用739. 每日温度建立单调栈直觉。你可以先打开本地动画页单调栈每日温度分步动画这个动画最值得盯住的是 4 步栈里保存的是“还没找到更高温度的下标”。当前温度一旦比栈顶对应温度更高就说明栈顶那一天终于能结算答案了。弹出栈顶后答案就是当前位置和那个下标的距离。当前下标入栈继续等待未来更高温度来结算它。拿temperatures [73, 74, 75, 71]举例前两步状态变化可以这样看步骤栈里保存什么当前元素做了什么为什么要存下标i 0[0]73先入栈因为后面要算“等几天”需要位置差i 1原栈顶是074 73弹出0answer[0] 1 - 0 1只有下标才能直接算距离结算后[1]当前下标1入栈它还没找到更高温度要继续等2. 这类题在面试里考什么这类题常用来区分“知道数据结构定义”和“会把结构用到题里”。面试官会看你能不能根据题意快速判断该用栈还是队列。你是否知道单调栈为什么保存的是还没找到答案的下标。你会不会在 Java 里正确使用ArrayDeque。真正拉开差距的不是你能不能背出 FIFO / LIFO而是你能不能解释为什么这个题里当前元素会和栈顶发生关系为什么另一些题又要用队列来保证处理顺序。3. 高频题清单题目来源难度高频属性20. 有效的括号LeetCode 热题 100Easy面试高频232. 用栈实现队列面试经典 150Easy基础高频155. 最小栈LeetCode 热题 100Medium高频739. 每日温度LeetCode 热题 100Medium高频 Medium4. 这类题最容易犯的 3 个错误明明是括号匹配却没有第一时间想到栈。用 JavaStack写题接口和性能习惯都不够好。单调栈只记住“维护递减 / 递增”没理解为什么存下标。5. 代表题精讲 1题目20. 有效的括号思路看到括号匹配第一反应就该是栈。因为右括号需要和“最近一个还没匹配的左括号”对应这正是后进先出的结构。做法遍历字符串。遇到左括号就入栈。遇到右括号先看栈是否为空为空直接失败。弹出栈顶看是否与当前右括号匹配。遍历结束后栈必须为空。Java 代码importjava.util.ArrayDeque;importjava.util.Deque;classSolution{publicbooleanisValid(Strings){DequeCharacterstacknewArrayDeque();for(charc:s.toCharArray()){if(c(||c[||c{){stack.push(c);}else{if(stack.isEmpty()){returnfalse;}chartopstack.pop();if((c)top!()||(c]top![)||(c}top!{)){returnfalse;}}}returnstack.isEmpty();}}复杂度时间复杂度O(n)空间复杂度O(n)边界提醒这题最容易漏掉的边界有两个一是字符串一开始就是右括号比如)二是遍历结束后栈里还有左括号比如(()。这两个边界正好对应代码里的两个关键判断stack.isEmpty()和最后的stack.isEmpty()返回值。如果这是面试现场你可以这样说这题是典型的栈题。因为每个右括号都要和最近一个未匹配的左括号对应所以适合用后进先出的结构。遍历时左括号入栈右括号就和栈顶匹配。最后如果栈为空说明所有括号都恰好配对。6. 代表题精讲 2题目739. 每日温度思路这题问的是对于每一天后面第一个更高温度要等几天。只要出现“右侧第一个更大 / 更小元素”就应该优先联想到单调栈。做法维护一个单调递减栈栈里存下标。遍历当前温度temperatures[i]。如果当前温度比栈顶下标对应的温度更高说明栈顶那一天终于找到了答案。弹出栈顶答案就是i - poppedIndex。最后把当前下标入栈。Java 代码importjava.util.ArrayDeque;importjava.util.Deque;classSolution{publicint[]dailyTemperatures(int[]temperatures){int[]answernewint[temperatures.length];DequeIntegerstacknewArrayDeque();for(inti0;itemperatures.length;i){while(!stack.isEmpty()temperatures[i]temperatures[stack.peek()]){intprevIndexstack.pop();answer[prevIndex]i-prevIndex;}stack.push(i);}returnanswer;}}复杂度时间复杂度O(n)空间复杂度O(n)边界提醒这题里栈必须保存下标而不是温度值本身。因为最终要填的是“还要等几天”本质是位置差。如果你只存温度值即使知道74比73大也没法直接算出应该填多少天。同时最后还留在栈里的那些下标不用再特殊处理它们在答案数组里天然保持0表示后面再也没有更高温度。如果这是面试现场你可以这样说这题我会归类为单调栈因为它本质是在找每个位置右侧第一个更大的元素。栈里保存的是还没找到答案的下标并且对应温度保持单调递减。一旦当前温度比栈顶更高就说明栈顶那一天的答案找到了可以直接更新天数差。7. 其余题模板与关键片段232. 用栈实现队列两个栈一个负责入一个负责出。if(outStack.isEmpty()){while(!inStack.isEmpty()){outStack.push(inStack.pop());}}这里的关键不是“两个栈”这四个字而是你要理解只有当outStack空了才需要把inStack倒过去。这样才能既保持队列顺序又避免每次操作都重复搬运。155. 最小栈可以用辅助栈同步维护最小值minStack.push(minStack.isEmpty()?val:Math.min(val,minStack.peek()));这题的本质不是把最小值现算出来而是让“当前栈顶对应的最小值”跟随每次入栈、出栈一起同步变化。8. 这三类结构怎么快速区分你可以用一个简单判断法最近匹配、撤销上一步、反向回退优先想栈。按进入顺序处理、层层扩散、先来先服务优先想队列。右侧第一个更大 / 更小元素、当前位置帮前面某些位置结算答案优先想单调栈。真正写代码前最好先用一句话说清我现在维护的是匹配顺序。我现在维护的是处理顺序。我现在维护的是一批还没找到答案的下标。9. 错题本记录方式这一类题建议记录我是如何判断出需要栈 / 队列 / 单调栈的。单调栈里保存的是值还是下标为什么。当前元素出现时栈顶元素代表什么状态。Java 中push/pop/offer/poll是否写混了。10. 面试前 3 分钟速记括号匹配优先想栈。层序遍历、BFS优先想队列。右侧第一个更大 / 更小元素优先想单调栈。单调栈通常存下标不直接存值。Java 刷题推荐ArrayDeque。11. 最后总结不要只背结构定义要知道当前元素在做什么如果你只能记住一句话那就是栈、队列、单调栈这类题真正的关键不是定义本身而是“当前元素出现时它和之前元素之间发生了什么关系”。面试时你只要能按这个顺序去讲思路就会稳定很多这题要维护的是匹配顺序、处理顺序还是等待结算的状态。当前元素出现时是入栈 / 入队等待还是负责结算之前的元素。我维护的是值、字符还是下标。最终答案是靠匹配成功、顺序处理完成还是位置差更新出来的。这样你不只是会做一道题而是真的开始掌握这一类数据结构题的共性。上期速递【Java实习面试算法冲刺】链表感谢阅读记得点赞、关注、收藏欢迎各位评论区交流