1. 栈与队列基础概念回顾在算法与数据结构的学习中栈和队列是最基础也是最重要的两种线性数据结构。它们看似简单但在实际算法问题中有着广泛的应用场景。今天我们就来深入探讨栈和队列在算法训练中的核心应用。栈Stack是一种后进先出LIFO的数据结构就像我们平时叠盘子一样最后放上去的盘子总是最先被取走。栈的基本操作包括push入栈、pop出栈、peek查看栈顶元素和isEmpty判断栈是否为空。在实际编程中栈常用于处理函数调用、表达式求值、括号匹配等问题。队列Queue则是一种先进先出FIFO的数据结构就像排队买票一样先来的人先得到服务。队列的基本操作包括enqueue入队、dequeue出队、front查看队首元素和isEmpty判断队列是否为空。队列常用于处理广度优先搜索BFS、任务调度等问题。2. 栈与队列的经典算法问题2.1 有效的括号问题这是栈最经典的运用场景之一。给定一个只包括 (, ), {, }, [, ] 的字符串判断字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合左括号必须以正确的顺序闭合解决思路初始化一个空栈遍历字符串中的每个字符遇到左括号就压入栈中遇到右括号时检查栈顶元素是否匹配最后检查栈是否为空def isValid(s: str) - bool: stack [] mapping {): (, }: {, ]: [} for char in s: if char in mapping: top_element stack.pop() if stack else # if mapping[char] ! top_element: return False else: stack.append(char) return not stack注意在实际编码时要特别注意边界条件比如空字符串、只有左括号或只有右括号的情况。2.2 用队列实现栈这是一个有趣的题目要求使用队列的基本操作来实现栈的功能。这考察我们对两种数据结构特性的理解。实现思路使用两个队列q1和q2push操作时将元素加入非空队列假设q1pop操作时将q1中的元素依次出队并入队到q2直到剩下最后一个元素这个元素就是栈顶元素交换q1和q2的引用from collections import deque class MyStack: def __init__(self): self.q1 deque() self.q2 deque() def push(self, x: int) - None: self.q1.append(x) def pop(self) - int: while len(self.q1) 1: self.q2.append(self.q1.popleft()) result self.q1.popleft() self.q1, self.q2 self.q2, self.q1 return result def top(self) - int: return self.q1[-1] if self.q1 else None def empty(self) - bool: return not self.q12.3 用栈实现队列与上一题相反这次需要用栈来实现队列的功能。这同样考察我们对数据结构特性的理解。实现思路使用两个栈s1和s2push操作时直接将元素压入s1pop操作时如果s2为空则将s1中的所有元素弹出并压入s2然后从s2弹出栈顶元素peek操作与pop类似但不弹出元素class MyQueue: def __init__(self): self.s1 [] self.s2 [] def push(self, x: int) - None: self.s1.append(x) def pop(self) - int: if not self.s2: while self.s1: self.s2.append(self.s1.pop()) return self.s2.pop() def peek(self) - int: if not self.s2: while self.s1: self.s2.append(self.s1.pop()) return self.s2[-1] if self.s2 else None def empty(self) - bool: return not self.s1 and not self.s23. 栈与队列的高级应用3.1 单调栈的应用单调栈是一种特殊的栈结构它保持栈内元素单调递增或单调递减。这种结构在解决某些特定问题时非常高效比如下一个更大元素问题。例题给定一个数组返回一个等长的数组对应位置存储着原数组中该元素右侧第一个比它大的元素值如果没有则存储-1。解决思路初始化一个空栈和结果数组从右向左遍历原数组当栈不为空且栈顶元素小于等于当前元素时弹出栈顶元素如果栈为空则结果数组中当前位置为-1否则为栈顶元素将当前元素压入栈中def nextGreaterElements(nums): n len(nums) res [-1] * n stack [] for i in range(n-1, -1, -1): while stack and stack[-1] nums[i]: stack.pop() if stack: res[i] stack[-1] stack.append(nums[i]) return res3.2 优先队列堆的应用优先队列是一种特殊的队列其中每个元素都有优先级出队时总是优先级最高的元素先出队。在Python中可以使用heapq模块来实现优先队列。例题合并K个升序链表。给定K个升序链表将它们合并为一个升序链表。解决思路使用最小堆来存储所有链表的头节点每次从堆中取出最小节点加入结果链表如果该节点有下一个节点将下一个节点加入堆中重复直到堆为空import heapq def mergeKLists(lists): dummy ListNode(0) curr dummy heap [] for i in range(len(lists)): if lists[i]: heapq.heappush(heap, (lists[i].val, i)) lists[i] lists[i].next while heap: val, idx heapq.heappop(heap) curr.next ListNode(val) curr curr.next if lists[idx]: heapq.heappush(heap, (lists[idx].val, idx)) lists[idx] lists[idx].next return dummy.next4. 常见问题与调试技巧4.1 栈溢出问题在使用递归实现算法时可能会遇到栈溢出问题。这是因为递归深度过大超过了系统栈的大小限制。解决方法包括将递归改为迭代使用尾递归优化如果语言支持增加系统栈大小不推荐例如二叉树的前序遍历可以用递归和迭代两种方式实现递归实现def preorderTraversal(root): res [] def helper(node): if not node: return res.append(node.val) helper(node.left) helper(node.right) helper(root) return res迭代实现使用栈def preorderTraversal(root): res [] stack [root] while stack: node stack.pop() if node: res.append(node.val) stack.append(node.right) stack.append(node.left) return res4.2 队列的空指针问题在使用队列时经常会出现空指针异常特别是在进行dequeue操作前没有检查队列是否为空。良好的编程习惯是在dequeue前总是检查队列是否为空使用哨兵值或异常处理来处理空队列情况在实现循环队列时要特别注意队空和队满的判断条件4.3 性能优化技巧对于频繁的插入删除操作使用链表实现的栈/队列比数组实现的性能更好在Python中collections.deque比list更适合实现队列因为它在两端的操作都是O(1)时间复杂度对于固定大小的队列可以考虑使用循环队列来节省空间在多线程环境下使用队列时考虑线程安全问题可以使用queue.Queue5. 实际工程中的应用案例5.1 浏览器前进后退功能浏览器的前进后退功能就是典型的栈应用场景。我们可以使用两个栈来实现一个栈存储访问历史后退栈另一个栈存储前进历史前进栈当点击后退时从后退栈弹出页面并压入前进栈当点击前进时从前进栈弹出页面并压入后退栈访问新页面时清空前进栈并将当前页面压入后退栈5.2 消息队列系统现代分布式系统中广泛使用消息队列来实现解耦和异步处理。常见的消息队列如RabbitMQ、Kafka等其核心就是队列数据结构。消息队列的主要特点包括生产者将消息放入队列消费者从队列中取出消息处理支持消息持久化支持消息确认机制支持发布/订阅模式5.3 函数调用栈程序执行时的函数调用就是通过栈来管理的。每次调用函数时会将返回地址和局部变量等信息压入调用栈函数返回时再从栈中弹出这些信息。理解这一点对于调试递归函数和异常堆栈非常有帮助。6. 算法竞赛中的技巧在算法竞赛中栈和队列经常被用来优化算法时间复杂度。以下是一些常见技巧使用单调栈可以在O(n)时间内解决一些看似需要O(n^2)的问题滑动窗口问题通常可以用双端队列来优化使用优先队列堆可以高效解决Top K问题在BFS中使用队列可以保证按层次遍历图或树使用栈可以模拟递归过程避免递归深度过大例如滑动窗口最大值问题可以用双端队列在O(n)时间内解决def maxSlidingWindow(nums, k): from collections import deque q deque() res [] for i, num in enumerate(nums): while q and nums[q[-1]] num: q.pop() q.append(i) if q[0] i - k: q.popleft() if i k - 1: res.append(nums[q[0]]) return res7. 扩展学习建议要真正掌握栈和队列的应用建议在LeetCode上多练习相关题目特别是中等难度的问题尝试用不同的编程语言实现相同的功能比较它们的性能差异阅读标准库中栈和队列的实现源码理解其底层原理在实际项目中寻找可以使用这些数据结构优化的场景学习更高级的数据结构如双端队列、优先队列、并发队列等一些推荐的进阶题目柱状图中最大的矩形单调栈滑动窗口最大值双端队列设计循环队列接雨水问题栈/双指针最小栈问题记住数据结构的掌握不在于死记硬背实现代码而在于理解其适用场景和性能特点。在实际编程中要根据具体问题选择最合适的数据结构。
企业数字化 ERP 产品动态
相关推荐
谷歌开源ARTEMIS:移动端AI自动化从原理到落地实践 移动端 AI 自动化这两年一直挂着“看着热闹、落地稀碎”的标签。手机上的日常操作,本质上就是“看屏幕、定计划、动手操作”,这跟 AI 智能体最擅长的“感知、决策、执行”几乎是一一对应的,可真的能让 AI 自己跑到手机里点按钮、滑页面、填表… · 2026/11/4 4:43:46
微电网容量配置的双层优化与工程实践 1. 微电网容量配置的双层优化逻辑剖析微电网规划本质上是一个多目标决策问题,既要考虑初期建设成本,又要兼顾长期运行经济性。传统单层优化模型往往将容量配置和运行调度割裂处理,导致规划结果在实际运行中出现"水土不服"。这就好比… · 2026/11/4 4:43:46
智慧物业管理系统架构设计与实施指南 1. 智慧物业管理系统核心架构解析武汉橙毅科技的智慧物业管理系统采用了典型的三层架构设计,这种架构在行业中被广泛验证为最稳定可靠的方案。我在实际部署过7个同类系统的经验中发现,这种分层方式能有效隔离业务逻辑,降低系统耦合度。1.1 基… · 2026/11/4 4:43:46
ShardingSphere SQL改写引擎原理与实践 1. ShardingSphere SQL改写引擎深度解析在分布式数据库架构中,SQL改写是一个至关重要的环节。开发人员编写的SQL语句面向的是逻辑库和逻辑表,这些SQL并不能直接在物理数据库中执行。SQL改写引擎的作用,就是将这些逻辑SQL转换为能够在真实数据… · 2026/11/4 5:25:14
ARTEMIS 开源框架:让 AI 像真人一样稳定操作 Android 手机 移动端自动化这个方向,过去几年一直有个尴尬的现实:能跑通 Demo 的方案很多,能稳定跑一整天的方案很少。我自己从早期用 ADB 脚本硬怼坐标点击,到后来折腾各种 UI 自动化框架,踩过的坑基本能写一本书。直到谷歌把 ARTE… · 2026/11/4 5:25:14
OpenClaw多Agent架构:企业级智能体协同实战 1. 项目概述OpenClaw多Agent数字员工军团是企业级智能体落地的进阶实践方案。不同于传统单Agent系统,1N架构通过一个中央调度器(1)协调多个专业Agent(N)协同工作,实现复杂业务流程的自动化处理。这种架构在… · 2026/11/4 5:25:14
多尺度因果关系建模在人机交互中的应用与实践 1. 项目背景与核心挑战人机交互领域正面临一个关键转折点——传统的"刺激-反应"模型已经无法解释复杂场景下的交互行为本质。去年我在设计一套医疗手术导航系统时,就深刻体会到这一点:当外科医生的操作手势、语音指令、眼动追踪数据同时输入系… · 2026/11/4 5:25:14
软考架构师论文:用架构决策证据突破45分线 软考架构师论文这一科,很多人栽得莫名其妙:选择题能过、案例能写,偏偏论文卡在45分线下。更让人憋屈的是,走出考场时自我感觉良好,觉得"结构完整、字数够、有项目",成绩出来却是43、44。我带过几… · 2026/11/4 5:25:14
GEO优化与三维九项认证技术解析 1. 项目背景与行业趋势解析"GEO优化"这个概念最近在空间数据服务领域频繁出现,它本质上是指基于地理空间信息(Geospatial)的优化技术体系。我注意到2026年3月即将实施的三维九项认证标准,这标志着行业即将进入一个全新的… · 2026/11/4 5:24:14
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46