导读:从今天起我将带来为期1个月的LeeCode算法突破专栏,希望大家和我一起突破自我(大神可以重温)。
今天开始刷栈与队列。
第一题:用两个栈实现队列
题目描述:用2个栈实现1个队列。队列的声明如下,请实现它的2个函数,appendTail和deleteHead,分别实现在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead操作返回-1)
示例1:
输入:
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]
输出:[null,null,3,-1]
示例2:
输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]
提示:
1 <= values <= 10000
最多会对 appendTail、deleteHead 进行 10000 次调用
对该题理解:本题第一眼看上去摸不到敲门,仔细推敲,栈特点是先进后出,而题目要求使用2个栈实现队列,如示例2中5,2输出也是5在2前面即先进先出。
具体到示例1,题目中的输入[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”] 这里是要执行的方法,从左到右执行。[[],[3],[],[]]对应上面的方法,是上面方法的参数。CQueue和deleteHead方法不需要指定数字,只有添加才需要指定数字。
1.创建队列,返回值为null
2.将3压入栈,返回值为null
3.将栈底的元素删除,也就是消息队列中先进来的元素,所以是deleteHead,返回该元素的数值,所以为3
4.继续删除栈底的元素,但是没有元素了,所以返回-1
所以就有了示例1中的输出:[null,null,3,-1]
具体示例2:
[“CQueue”,“deleteHead”,“appendTail”,“appendTail”,“deleteHead”,“deleteHead”]
[[],[],[5],[2],[],[]]
1.创建队列,返回值为null
2.删除栈底的元素,但是没有元素,所以返回-1
3.把5压入栈,返回null
4.把2压入栈,返回null
5.删除栈底的一个元素,也就是消息队列中先进来的元素,所以是deleteHead,就是最先进来的5,返回值为5,
6.删除栈底的一个元素,就是后进来的2,返回值为2,
所以就有了下面的输出
输出:[null,-1,null,null,5,2]
因此使用Python3实现该算法:
(一个队列具备的两个功能分别由两个栈来完成:栈A实现入队功能,栈B实现出队功能)
class CQueue:
def __init__(self):
self.A, self.B = [], [] #定义2个栈
def appendTail(self, value: int) -> None:
self.A.append(value) #加入队尾函数
def deleteHead(self) -> int:
if self.B: return self.B.pop() #2.1,栈B不为空,直接返回B中元素,使用pop()
if not self.A: return -1 #栈均为空,返回-1
while self.A:
self.B.append(self.A.pop()) #将栈A元素全部转移至栈B实现元素倒排,并返回栈B的栈顶元素
return self.B.pop()
总结:
代码实现了2个函数的功能构造:
(1)appendTail()函数即加入队尾函数,直接将数字 val 加入栈 A 即可。
(2)删除队首deleteHead()函数,重点函数,分为3种情况
1)当栈 B 不为空: B中仍有已完成倒序的元素,因此直接返回 B 的栈顶元素。
2)当 A 为空: 即两个栈都为空,无元素,因此返回−1 。
3)将栈 A 元素全部转移至栈 B 中,实现元素倒序,并返回栈 B 的栈顶元素。