用队列实现栈(LeetCode 225):双队列模拟 LIFO 的完整设计与复杂度分析
教程文档知识库【免费下载链接】AlgoNote⛽️「算法通关手册」从零开始的「算法与数据结构」学习教程200 道「算法面试热门题目」1000 道「LeetCode 题目解析」持续更新中项目地址https://gitcode.com/gh_mirrors/le/AlgoNote点击查看免费下载本文基于「算法通关手册」0225. 用队列实现栈题解 展开讲解如何仅使用两个队列及其标准操作模拟出后进先出LIFO的栈语义覆盖题目约束、双队列入栈反转法、完整可运行代码、复杂度分析与手工推演并结合仓库内顺序队列、循环队列、链式队列与双向队列的源码实现帮读者透彻理解这一经典的「数据结构互模拟」设计题。一、题目概述题目链接与分类题目编号0225. 用队列实现栈Implement Stack using Queues标签栈、设计、队列难度简单在「算法通关手册」中该题同时收录于 题解总览、题目分类列表 以及 面试 100 题 / 200 题清单属于面试高频的「数据结构设计」类题目。题目要求仅使用两个队列实现一个**后入先出LIFO**的栈并支持普通栈的四种操作void push(int x)将元素x压入栈顶int pop()移除并返回栈顶元素int top()返回栈顶元素不移除boolean empty()如果栈为空返回True否则返回False。要求实现MyStack类同时必须满足以下约束只能使用队列的基本操作即push to back队尾入队、peek/pop from front查看/弹出队头、size队列大小和is empty判空所使用的语言如果不原生支持队列可以使用list列表或deque双端队列来模拟队列只要走的是标准队列操作即可。本题在 LeetCode 上还允许「仅使用一个队列」的做法但题面标准约束为两个队列本文按题解的双队列方案展开单队列优化作为延伸思路在文末给出。示例输入 [MyStack, push, push, top, pop, empty] [[], [1], [2], [], [], []] 输出 [null, null, null, 2, 2, false] 解释 MyStack myStack new MyStack(); myStack.push(1); myStack.push(2); myStack.top(); // 返回 2 myStack.pop(); // 返回 2 myStack.empty(); // 返回 False从示例可以看出按push(1)、push(2)的顺序入栈后top()和pop()得到的都是最后压入的2这正是栈「后进先出」语义的体现——而队列本身是「先进先出FIFO」因此需要用两个队列做一次「翻转」。二、前置知识栈与队列的本质差异2.1 栈后进先出LIFO栈只允许在一端栈顶进行插入和删除最后放入栈的元素最先被取出。仓库教程 栈基础 给出了三种经典操作入栈Push在栈顶加入新元素出栈Pop移除并返回栈顶元素查看栈顶Peek只查看栈顶元素不移除。仓库中的顺序栈实现 用列表 栈顶指针top完成这三个操作入栈、出栈、查看栈顶均为O(1)。2.2 队列先进先出FIFO队列只允许在队尾插入元素入队在队头删除元素出队最先进入队列的元素最先被取出。仓库教程 队列基础 定义了两种基本操作入队enqueue在队尾插入元素出队dequeue从队头删除元素。队列有四种常见实现方式仓库中均有对应源码实现方式仓库源码特点顺序存储队列queue_sequential_queue.py数组实现队满后存在「假溢出」顺序存储循环队列queue_circularSequential_queue.py通过取模运算复用空间判满用(rear 1) % size front链式存储队列queue_link_queue.py单链表实现front/rear指针分别标记队头前驱与队尾双向队列dequequeue_deque.py支持队头/队尾双侧入出本题代码即基于它2.3 核心矛盾栈要求「后进先出」队列天然是「先进先出」。若只用一个队列push到队尾的元素永远最后才被pop出来这与栈顶先出的语义正好相反。解决办法是在入栈时就把元素顺序翻转——每次新元素入栈时让队列中已存在的元素整体后移使新元素始终占据队头这样队头即栈顶pop、top就退化为普通的队头操作。三、解题思路双队列法3.1 设计要点使用两个队列pushQueue用作入栈缓冲popQueue用作存储与出栈。push操作将新元素压入pushQueue再把popQueue中之前保存的元素从队头开始依次转移进pushQueue。转移完成后pushQueue的队头是新加入的元素队尾是之前的元素而popQueue变空随后交换pushQueue与popQueue的角色保持pushQueue为空、popQueue中存放全部元素。pop操作由于popQueue队头即栈顶直接取队头元素即可。top操作直接返回popQueue队头元素不移除。empty操作判断popQueue是否为空。3.2 为什么push后要交换交换动作的本质是「角色互换」。如果不交换下一次push时就需要判断新元素该进入哪个队列逻辑会复杂交换后可以保持不变量「pushQueue恒为空popQueue恒为当前栈的全部元素」使每次push的逻辑完全一致新元素入pushQueue此时它自己一个元素也是队头将popQueue全部元素依次搬到pushQueue队尾——由于popQueue的队头正是上一次的栈顶搬运后pushQueue的队头自然成为新栈顶交换两个队列的引用恢复不变量。3.3 代码实现import collections class MyStack: def __init__(self): Initialize your data structure here. self.pushQueue collections.deque() # 入栈缓冲队列约定恒为空 self.popQueue collections.deque() # 元素存储队列队头即栈顶 def push(self, x: int) - None: Push element x onto stack. self.pushQueue.append(x) # 新元素先进入缓冲队列 while self.popQueue: # 将旧元素整体搬到新元素之后 self.pushQueue.append(self.popQueue.popleft()) # 交换两个队列popQueue 重新持有全部元素pushQueue 恢复为空 self.pushQueue, self.popQueue self.popQueue, self.pushQueue def pop(self) - int: Removes the element on top of the stack and returns that element. return self.popQueue.popleft() # 队头即栈顶直接弹出 def top(self) - int: Get the top element. return self.popQueue[0] # 查看队头元素不移除 def empty(self) - bool: Returns whether the stack is empty. return not self.popQueue # popQueue 为空即栈为空 # Your MyStack object will be instantiated and called as such: # obj MyStack() # obj.push(x) # param_2 obj.pop() # param_3 obj.top() # param_4 obj.empty()代码说明使用collections.deque模拟队列append对应push to back队尾入队popleft对应pop from front队头出队popQueue[0]对应peek from front完全符合题目「只能用标准队列操作」的约束popQueue[0]是双向队列的下标访问若用list模拟队列则等价于popQueue[0]list 队头或queue[0]若题目要求「只能使用两个队列」之外的额外约束本实现不依赖任何非标准操作可直接提交。3.4 复杂度分析时间复杂度push每次需要把popQueue中已有元素逐个搬移若当前栈中已有n个元素则耗时O(n)pop直接弹出队头O(1)top直接查看队头O(1)emptyO(1)。空间复杂度两个队列合计保存全部元素O(n)。说明因为入栈是O(n)若连续执行n次push总代价为O(n²)单队列方案的入栈同样是O(n)但可以省去交换环节空间上只用一个队列。两种方案在最坏情况下的渐进复杂度相同。四、手工推演一次完整的调用序列以示例操作序列push(1) → push(2) → top() → pop() → empty()为例逐步推演push(1)pushQueue[1]popQueue为空无搬运交换后popQueue[1]pushQueue[]。push(2)pushQueue[2]把popQueue中的1搬到队尾得到pushQueue[2, 1]交换后popQueue[2, 1]队头是2pushQueue[]。top()返回popQueue[0]即2。pop()popleft()弹出2popQueue[1]。empty()popQueue非空返回False。可以看到关键一步发生在push(2)通过「新元素先入缓冲队旧元素整体搬到新元素之后」的搬运2始终位于队头从而pop、top都能以O(1)拿到栈顶。若再push(3)则执行pushQueue[3]搬运popQueue[1]得到[3, 1]交换后popQueue[3, 1]栈顶3依然在队头——不变量始终成立。五、仓库源码印证队列的底层实现本题代码依赖的是「标准队列操作」。仓库内提供了多套队列实现帮助理解deque背后到底发生了什么顺序队列queue_sequential_queue.pyenqueue将rear右移后写入dequeue将front右移后读出缺点是队满后即使前方有空位也无法复用即「假溢出」。循环队列queue_circularSequential_queue.py用取模运算(rear 1) % size与(front 1) % size让指针循环移动判空front rear、判满(rear 1) % size front空间利用率更高——这也是 03_03_queue_basic.md 中重点讲解的实现。链式队列queue_link_queue.pyenqueue在链表尾部追加节点并更新reardequeue取出front.next并前移front无需预先分配容量。双向队列queue_deque.py同时支持push_front/push_back/pop_front/pop_back本题代码选用的collections.deque正属此类其队头出队popleft均摊为O(1)因此双队列法中的搬运环节整体代价仍然可控。无论底层是数组、循环数组还是链表对MyStack而言都只需要「队尾入队、队头出队、查看队头、判空」四个能力这正是本题考察的抽象与接口设计用受限的数据结构组合出另一种数据结构的行为。六、姊妹题对照用栈实现队列0232本题与仓库内另一道经典设计题 0232. 用栈实现队列 互为镜像维度0225 用队列实现栈0232 用栈实现队列目标用 FIFO 模拟 LIFO用 LIFO 模拟 FIFO核心策略入栈时反转push 时搬运旧元素到新元素之后出队时反转inStack整体倒入outStack关键操作push为O(n)pop/top为O(1)push为O(1)pop/peek均摊O(1)空间复杂度O(n)O(n)0232 题的思路是push直接压入inStack当outStack为空时把inStack元素依次弹出压入outStack顺序恰好反转于是outStack栈顶即队列队头。它把「反转」延迟到出队时进行从而换来push的O(1)与pop、peek的均摊O(1)。两道题放在一起对比练习能更深刻地理解「何时反转」「在哪一端反转」这一设计决策。七、延伸思考单队列方案若允许只用一个队列push时先把元素入队再将队列前size - 1个元素依次出队并入队同样能让新元素滚到队头pop、top、empty逻辑不变。空间从两个队列降为一个但入栈仍为O(n)。均摊优化参考 0232 的思路是否能把「反转」从push挪到pop让入栈变成O(1)、出栈变为均摊O(1)在双队列模型下队列本身允许从队头窥视实现方式与双栈有所不同可作为进阶思考题。接口抽象价值本题的设计意义在于验证「任意具备标准队列操作的具体实现都能组合出栈的语义」无论底层是数组、循环数组、链表还是双向队列上层代码完全不用改动——这正是数据结构「逻辑结构」与「存储结构」分离思想的直观体现。相关资源本题题解docs/solutions/0200-0299/implement-stack-using-queues.md姊妹题0232. 用栈实现队列题解队列基础教程docs/03_stack_queue_hash_table/03_03_queue_basic.md栈基础教程docs/03_stack_queue_hash_table/03_01_stack_basic.md队列相关源码codes/python/03_stack_queue_hash_table/含顺序队列、循环队列、链式队列、双向队列与顺序栈实现题目分类与题解索引00_06_categories_list.md、00_05_solutions_list.md赞分享教程文档知识库【免费下载链接】AlgoNote⛽️「算法通关手册」从零开始的「算法与数据结构」学习教程200 道「算法面试热门题目」1000 道「LeetCode 题目解析」持续更新中项目地址https://gitcode.com/gh_mirrors/le/AlgoNote点击查看免费下载相关推荐LeetCode 225 题解用队列实现栈Implement Stack using Queues——Go 双队列实现与测试解析LeetCode 225 题解用队列实现栈Implement Stack using Queues——Go 双队列实现与测试解析 导读 本篇围绕 Leet示例工程用队列实现栈LeetCode 225单队列旋转法图解与 Java / JS / C 三语言实现用队列实现栈LeetCode 225单队列旋转法图解与 Java / JS / C 三语言实现 导读 本文基于 algorithm base http文档教程知识库用队列实现栈三种解法与多语言实现深度剖析LeetCode 225 题用队列实现栈三种解法与多语言实现深度剖析LeetCode 225 题 本文围绕 LeetCode 225「用队列实现栈」展开系统讲解双队列、单队列、队列示例工程教程上一篇【亲测免费】 数据探查利器Capital One的DataProfiler下一篇Laravel 法语语言包翻译缺口全景Passkeys、加密环境文件与 encoding 验证规则的 12 个待补条目创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

awesome-agentic-ai-zh 渐进式披露重构实战:用可见主线、`<details>` 收合与 reader-UX 门禁重建 Track A(A1–A3)学习路径

awesome-agentic-ai-zh 渐进式披露重构实战:用可见主线、`<details>` 收合与 reader-UX 门禁重建 Track A(A1–A3)学习路径

教程文档AI Agent人工智能大模型 【免费下载链接】awesome-agentic-ai-zh A trilingual (繁中 / English / 简中) learning roadmap for agentic AI: from LLM basics to multi-agent systems, with 240 curated resources and hands-on examples. 中文 AI agent 學習地圖。 项…

2026/9/29 5:41:04 阅读更多 →
Elsa 3 输出转换器(Output Converters)完全指南:在绑定边界同步、显式、可发现地转换 Activity 输出

Elsa 3 输出转换器(Output Converters)完全指南:在绑定边界同步、显式、可发现地转换 Activity 输出

后端工作流自动化流程编排低代码 【免费下载链接】elsa-core The Workflow Engine for .NET 项目地址: https://gitcode.com/gh_mirrors/el/elsa-core 点击查看 免费下载 本篇技术指南聚焦 Elsa Workflow Engine(.NET)的 Output Converters&…

2026/9/29 5:41:04 阅读更多 →
KnowStreaming 贡献指南:从 Issue 认领、Commit 规范到 PR 合并的完整协作流程

KnowStreaming 贡献指南:从 Issue 认领、Commit 规范到 PR 合并的完整协作流程

后端消息队列运维可观测性 【免费下载链接】KnowStreaming 一站式云原生实时流数据平台,通过0侵入、插件化构建企业级Kafka服务,极大降低操作、存储和管理实时流数据门槛 项目地址: https://gitcode.com/gh_mirrors/kn/KnowStreaming 点击查看…

2026/9/29 5:41:04 阅读更多 →

最新新闻

使用C#代码更改或删除 PDF 中的超链接

使用C#代码更改或删除 PDF 中的超链接

PDF 文档中的超链接可以帮助用户快速跳转到指定页面或打开相关文档,让 PDF 文件更加便捷、易用。但如果链接目标发生变化,或者链接指向了错误的页面,就可能给文档使用者带来困扰或误解。因此,及时修改或删除 PDF 文档中的错误或无…

2026/9/30 12:59:10 阅读更多 →
企业知识库Rerank落地实战:从召回瓶颈到精排调优

企业知识库Rerank落地实战:从召回瓶颈到精排调优

1. 企业智能知识库的检索瓶颈与Rerank的切入点做过企业知识库的人都有一个共同感受:向量检索上线第一天效果惊艳,第二周开始被业务方吐槽“答非所问”。用户搜“差旅报销标准”,返回的却是“差旅申请流程”;问“年假怎么算”&…

2026/9/30 12:59:10 阅读更多 →
多路复用:智能体基建的关键连接层,统一接入模型与工具

多路复用:智能体基建的关键连接层,统一接入模型与工具

最近好几个技术群都在聊同一个话题:手里的模型 API 越来越多,代码助手、文档问答、图表生成、终端工具各干各的,每一个单独拎出来都能干活,但放在一起就“各干各的活”。我自己在搭内部效率工具链的时候也有同样的感受——单点工具…

2026/9/30 12:59:10 阅读更多 →
数据编排框架深度对比:Airflow、Luigi与Oozie的定位与选型

数据编排框架深度对比:Airflow、Luigi与Oozie的定位与选型

数据编排框架这个话题,我在不同公司搬了三次砖,接触过三个不同的技术栈:最早在传统数仓团队用Oozie跑Hive任务,后来去一家中型互联网公司搭了Luigi,现在所在的团队则把Airflow作为核心调度平台。这三个框架都是开源的&…

2026/9/30 12:59:10 阅读更多 →
RAG系统生产落地:AI网关架构设计与工程实践

RAG系统生产落地:AI网关架构设计与工程实践

1. 从一次线上事故说起:为什么RAG系统需要一个AI网关去年年底,我帮一个做企业知识库的团队排查线上问题。他们的RAG系统上线三个月,检索命中率从最初的82%一路跌到61%,用户投诉越来越多。我上去看了一圈,发现问题根本不…

2026/9/30 12:59:10 阅读更多 →
Node.js+Vue全栈实战:校园足球比赛网站开发

Node.js+Vue全栈实战:校园足球比赛网站开发

1. 技术方案选型与系统架构设计1.1 为什么是Node.js Vue组合前阵子学校体育部想搞一个校园足球联赛的报名和信息公示系统,我接了这个需求。当时第一反应就是用传统的老三样:HTML CSS jQuery 配上一个PHP后台,但后来想了想,这种…

2026/9/30 12:58:09 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 8:16:59 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/29 8:24:48 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/29 3:55:56 阅读更多 →