灵感来源
- 保持更新,努力学习
- python脚本学习
用栈实现队列
解题思路
队列的特性是先进先出(FIFO),而栈是后进先出(LIFO)。要用栈实现队列,需要使用两个栈来反转元素的顺序:
- 入队栈(pushStack):负责处理所有的入队操作,新元素总是压入这个栈。
- 出队栈(popStack):负责处理出队和查看队首操作。当需要出队时,如果此栈为空,则将入队栈的所有元素弹出并压入此栈,以此反转元素顺序。
这种方法确保了每个元素最多被移动两次(从入队栈到出队栈),从而使每个操作的均摊时间复杂度为 O (1)。
class MyQueue:
def __init__(self):
# 初始化两个栈:入队栈和出队栈
self.pushStack = [] # 用于入队操作
self.popStack = [] # 用于出队和查看队首操作
def push(self, x: int) -> None:
# 入队操作:直接将元素压入入队栈
self.pushStack.append(x)
def pop(self) -> int:
# 出队操作:
self._transfer() # 先检查并转移元素
return self.popStack.pop() # 从出队栈弹出元素
def peek(self) -> int:
# 查看队首操作:
self._transfer() # 先检查并转移元素
return self.popStack[-1] # 返回出队栈的栈顶元素
def empty(self) -> bool:
# 判断队列是否为空:当两个栈都为空时,队列为空
return not self.pushStack and not self.popStack
def _transfer(self) -> None:
# 辅助方法:将入队栈的元素转移到出队栈,当出队栈为空时执行
if not self.popStack: # 只有出队栈为空时才转移
while self.pushStack: # 将入队栈的所有元素弹出并压入出队栈
self.popStack.append(self.pushStack.pop())
逐行解释
class MyQueue:
def __init__(self):
# 初始化两个栈:pushStack 用于入队操作,popStack 用于出队和查看队首
self.pushStack = [] # 入队栈,新元素总是压入此栈
self.popStack = [] # 出队栈,元素从 pushStack 转移过来以反转顺序
def push(self, x: int) -> None:
# 入队操作:直接将元素压入入队栈
# 时间复杂度:O(1)
self.pushStack.append(x)
def pop(self) -> int:
# 出队操作:
# 1. 先调用 _transfer() 确保 popStack 中有元素(如果为空则从 pushStack 转移)
# 2. 弹出 popStack 的栈顶元素
self._transfer()
return self.popStack.pop()
def peek(self) -> int:
# 查看队首操作:
# 1. 先调用 _transfer() 确保 popStack 中有元素
# 2. 返回 popStack 的栈顶元素(不弹出)
self._transfer()
return self.popStack[-1]
def empty(self) -> bool:
# 判断队列是否为空:
# 当且仅当两个栈都为空时,队列为空
return not self.pushStack and not self.popStack
def _transfer(self) -> None:
# 辅助方法:将 pushStack 中的所有元素转移到 popStack 中
# 确保元素顺序被反转(栈的 LIFO 特性实现队列的 FIFO)
# 仅在 popStack 为空时执行转移,避免重复操作
if not self.popStack: # 只有当 popStack 为空时才需要转移
while self.pushStack: # 将 pushStack 的所有元素弹出并压入 popStack
self.popStack.append(self.pushStack.pop())