剑指 Offer 09. 用两个栈实现队列

36 阅读2分钟

前言:剑指offer刷题系列

问题:

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTaildeleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

示例:

["CQueue","appendTail","deleteHead","deleteHead","deleteHead"]
[[],[3],[],[],[]]
输出:[null,null,3,-1,-1]

思路:

很久之前就听说过这个题,虽然我对栈和队列这一系列的数据结构的定义概念很熟悉,但是没怎么接触过代码,不会用代码实现过,就感到畏惧一直没写,拖到今天才写。

a栈的特点是先进后出,将a栈里的元素弹出到b栈,然后b栈的特点,相对于整个数据流来说,就是后进先出。 而队列的特点是先进先出,所以我们往a栈进元素,从b栈出元素。 注意,只有在b栈为空时,我们需要把a栈中的元素全都弹出到b栈中。

加入队尾 appendTail()函数: 将数字 val 加入栈a即可。b栈不需要进行操作。 删除队首deleteHead()函数: 有以下三种情况。 当栈 b 不为空: B中仍有已完成倒序的元素,因此直接返回 b 的栈顶元素。 否则,当 a 为空: 即两个栈都为空,无元素,因此返回 −1。 否则: 将栈 a 元素全部转移至栈 b 中,实现元素倒序,并返回栈 b 的栈顶元素。

基于上述思考,代码如下:

class CQueue:

    def __init__(self):
        self.a,self.b = [],[]

    def appendTail(self, value: int) -> None:
        self.a.append(value)

    def deleteHead(self) -> int:
        if self.b:return self.b.pop()
        if not self.a:return -1
        while self.a:
            self.b.append(self.a.pop())
        return self.b.pop()

执行结果如下图:

image-20230811113459070.png

复习的知识点:

栈:后进先出,只能删除栈顶元素,不能删除栈底元素。

队列:先进先出,只能删除队头元素,不能删除队尾元素。当然也有例外,有操作受限的队列。如:入队受限队列(不太记得是不是这个名字了)就是只有一边可以入队,但是两边都可以出队,即,队头队尾元素都可以删除;同样也有队头队尾都可以入队的队列。