《剑指 Offer》学习记录:题 9:用两个栈实现队列
题 9:用两个栈实现队列#
题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。——《剑指 Offer》P68
解题思路#
队列是先进先出的结构,将一系列的数据入队列后全部出队列,这些数据的顺序不会改变。栈是先进后出的结构,将一系列的数据入栈后全部出栈,这些数据将会逆序出栈。如果将这些逆序的数据再次全部入栈,然后全部出栈就可以恢复这些顺序原有的序列。借助 2 个栈实现队列的关键时,在合适的时候进行出栈操作。例如将 1,2,3 这些数据做入队列操作,也就是将这些数据入第一个栈。
如果要执行出队列操作,由于第一个栈直接出栈会导致顺序逆序,所以要将所有元素出栈进入第二个栈。
此时数据的顺序已经恢复,出队列操作就直接在第二个栈做出栈操作即可。
将数据 4 入队列,也是直接将这些数据入第一个栈就行。
而如果要做出队列操作,注意第二个栈中已经有一些数据了,因此在第二个栈做出栈操作即可。
由此我们可以总结出入队列和出队列操作的时机,入队列操作只需要将数据入第一个栈。出队列操作则需要分类讨论,如果第二个栈有数据,则直接对第二个栈做出栈操作即可。如果第二个栈没有数据,需要先将第一个栈的数据全部出栈后入第二个栈,再对第二个栈做出栈操作。
题解代码#
class CQueue:
def __init__(self):
self.stack1 = []
self.stack2 = []
def appendTail(self, value: int) -> None:
self.stack1.append(value)
def deleteHead(self) -> int:
if len(self.stack2) != 0: #第二个栈中有数据
return self.stack2.pop()
elif len(self.stack1) == 0: #队列中没有任何元素
return -1
while len(self.stack1) > 0: #第二个栈中无数据且第一个栈不为空
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
时空复杂度#
入队列操作只需要将数据入第一个栈,时间复杂度为 O(1)。
出队列操作时,最坏情况需要将第一个栈中的 n 个元素出栈后进入第二个栈,时间复杂度为 O(n)。
参考资料#
《剑指 Offer(第2版)》,何海涛 著,电子工业出版社
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2020-05-24 用树结构存储的查找博客(笑)
2020-05-24 PTA习题解析——修理牧场(2 种解法)