目录
LeetCode232.用栈实现队列
1. 思路
使用栈来模拟队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈,这里要注意输入栈和输出栈的关系。
在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入,不然会导致顺序变乱),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。
最后如何判断队列为空呢?如果进栈和出栈都为空的话,说明模拟的队列为空了。
在代码实现的时候,会发现pop() 和 peek()两个函数功能类似,代码实现上也是类似的,可以思考一下如何把代码抽象一下。
2. 代码实现
class MyQueue(object):
def __init__(self):
# 这里必须要用self,不然后面不能传递值
self.stack_in = []
self.stack_out = []
# time:O(1);space:O(1)
def push(self, x):
"""
:type x: int
:rtype: None
"""
self.stack_in.append(x)
# time:O(N);space:O(N)
def pop(self):
"""
:rtype: int
"""
if self.empty():
return None
elif self.stack_out:
return self.stack_out.pop()
else:
# 这里也可以用while(self.stack_in)
for i in range (len(self.stack_in)):
element = self.stack_in.pop()
self.stack_out.append(element)
return self.stack_out.pop()
# time:O(N);space:O(N)
def peek(self):
"""
:rtype: int
"""
# if self.empty():
# return None
result = self.pop()
self.stack_out.append(result)
return result
# time:O(1);space:O(1)
def empty(self):
"""
:rtype: bool
"""
return not(self.stack_in or self.stack_out)
# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()
3. 复杂度分析
入队self.push()
时间复杂度O(1),直接把元素append到stack_in栈中的最后就行;
空间复杂度O(1),stack_in 栈多储存一个元素;
出队self.pop()
时间复杂度O(N),需要把所有元素全部压入stack_out栈中,再出栈一个元素;
空间复杂度O(N)需要额外的N个内存来储存队列中的元素;
取队首元素self.peek()
因为需要调用self.pop(),然后再push,时间复杂度O(N);空间复杂度O(N);
判断空self.empty()
只需要判断两个栈是否为空即可,时间复杂度O(1),空间复杂度O(1)
4. 思考
-
可以看出peek()的实现,直接复用了pop()。
这样的项目代码会越来越乱,一定要懂得复用,功能相近的函数要抽象出来,不要大量的复制粘贴,很容易出问题!(踩过坑的人自然懂)
因为一旦代码需要因为业务需求去修改某些地方,如果你是抽象出来的,就只用改抽象的子函数即可,如果你是到处复制粘贴的话,你会忘记你在哪些地方粘贴了,就是项目中的一个定时炸弹;
工作中如果发现某一个功能自己要经常用,同事们可能也会用到,自己就花点时间把这个功能抽象成一个好用的函数或者工具类,不仅自己方便,也方面了同事们。同事们就会逐渐认可你的工作态度和工作能力,自己的口碑都是这么一点一点积累起来的!在同事圈里口碑起来了之后,你就发现自己走上了一个正循环,以后的升职加薪才少不了你!哈哈哈
再多说一些代码开发上的习惯问题,在工业级别代码开发中,最忌讳的就是 实现一个类似的函数,直接把代码粘过来改一改就完事了。
-
在初始化定义的时候,一定要写self.stack_in 以及self.stack_out,这样这个栈才能在后序定义的函数里操作;
-
本题不涉及什么高深的算法知识,就是用两个栈模拟队列的行为;
-
本题只用考虑用户的合法操作,不合法操作,比如在队列为空的时候还弹出队列中的元素可以暂不考虑。
Reference:
用栈实现队列 - 用栈实现队列 - 力扣(LeetCode)
本题学习时间:80分钟。