232.用栈实现队列
使用栈实现队列的下列操作:
push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。
class MyQueue:
def __init__(self):
"""
in主要负责push,out主要负责pop
"""
self.stack_in = []
self.stack_out = []
def push(self, x: int) -> None:
"""
有新元素进来,就往in里面push
"""
self.stack_in.append(x)
def pop(self) -> int:
"""
Removes the element from in front of queue and returns that element.
"""
if self.empty():
return None
if self.stack_out:
return self.stack_out.pop()
else:
for i in range(len(self.stack_in)):
self.stack_out.append(self.stack_in.pop())
return self.stack_out.pop()
def peek(self) -> int:
"""
Get the front element.
"""
ans = self.pop()
self.stack_out.append(ans)
return ans
def empty(self) -> bool:
"""
只要in或者out有元素,说明队列不为空
"""
return not (self.stack_in or self.stack_out)
-
__init__(self)
:初始化方法,创建了两个空栈 stack_in 和 stack_out。stack_in 主要负责 push 操作,stack_out 主要负责 pop 和 peek 操作。 -
push(self, x: int) -> None
:将元素 x 推入队列的操作。这个方法将元素 x 添加到 stack_in 栈顶,实现了 push 操作。 -
pop(self) -> int
:弹出队列的前端元素并返回该元素。首先,它检查队列是否为空,如果为空,则返回 None 表示队列为空。否则,它检查 stack_out 是否为空,如果不为空,则从 stack_out 栈顶弹出元素并返回。如果 stack_out 为空,则将 stack_in 中的元素依次弹出并推入 stack_out,然后从 stack_out 栈顶弹出元素并返回,实现了 pop 操作。 -
peek(self) -> int
:获取队列的前端元素,但不弹出。首先,它调用 pop 方法获取队列前端元素并存储在 ans 中,然后将 ans 推回 stack_out 栈顶,最后返回 ans,实现了 peek 操作。 -
empty(self) -> bool
:检查队列是否为空。如果 stack_in 或 stack_out 中有元素,说明队列不为空,返回 False;否则,返回 True,表示队列为空。
这个队列实现了队列的基本功能,并且通过两个栈来实现队列的 push、pop 和 peek 操作。这种数据结构通常称为两个栈模拟队列。
两个栈模拟队列是一种数据结构设计,通过使用两个栈来模拟队列的行为。这种设计允许你在队列的两端执行操作,即在队列的前端进行 pop 和 peek 操作,而在队列的后端进行 push 操作。下面是对两个栈模拟队列的详细解释:
1. **两个栈**:在两个栈模拟队列中,通常会有两个栈,一个用于入队列操作(push),另一个用于出队列操作(pop 和 peek)。这两个栈分别称为 `stack_in` 和 `stack_out`。
2. **push 操作**:当需要向队列中添加元素时,将元素推入 `stack_in` 栈顶。这个操作与队列的入队列操作类似。
3. **pop 操作**:当需要从队列中移除并返回元素时,可以从 `stack_out` 栈顶弹出元素。但如果 `stack_out` 栈为空,需要执行以下步骤:
- 从 `stack_in` 栈顶依次弹出元素,并将它们推入 `stack_out` 栈。这个操作会使得元素的顺序反转,从而实现队列的 FIFO(先进先出)行为。
- 之后,从 `stack_out` 栈顶弹出的元素就是队列的前端元素,它被返回。
4. **peek 操作**:peek 操作用于获取队列的前端元素,但不移除它。可以调用 pop 操作获取前端元素,将它推回 `stack_out` 栈顶,然后返回它。
5. **empty 操作**:用于检查队列是否为空。如果 `stack_in` 和 `stack_out` 均为空,那么队列就为空。
这种两个栈模拟队列的实现方式允许你在队列的前端进行操作,同时保持队列的先进先出特性。虽然这种实现方式在一些情况下可能会涉及元素的多次移动,但它可以有效地模拟队列的行为,并且在某些情况下非常有用。
225. 用队列实现栈
使用队列实现栈的下列操作:
- push(x) -- 元素 x 入栈
- pop() -- 移除栈顶元素
- top() -- 获取栈顶元素
- empty() -- 返回栈是否为空
class MyStack:
def __init__(self):
self.que = deque()
def push(self, x: int) -> None:
self.que.append(x)
def pop(self) -> int:
if self.empty():
return None
for i in range(len(self.que)-1):
self.que.append(self.que.popleft())
return self.que.popleft()
def top(self) -> int:
# 写法一:
# if self.empty():
# return None
# return self.que[-1]
# 写法二:
if self.empty():
return None
for i in range(len(self.que)-1):
self.que.append(self.que.popleft())
temp = self.que.popleft()
self.que.append(temp)
return temp
def empty(self) -> bool:
return not self.que
这段代码实现了一个栈(Stack)的数据结构,使用一个双端队列(deque)来模拟栈的行为。这个栈支持 `push`、`pop`、`top` 和 `empty` 四种操作,以下是对每个方法的详细解释:
1. `__init__(self)`:初始化方法,创建一个空的双端队列 `que`,用于存储栈中的元素。
2. `push(self, x: int) -> None`:将元素 `x` 推入栈的操作。这个方法直接在队列的末尾(右侧)添加元素,模拟了栈的入栈操作。
3. `pop(self) -> int`:弹出栈顶元素并返回。如果栈为空,返回 `None`。具体操作如下:
- 如果栈不为空,通过循环将队列中除了最后一个元素外的所有元素出队列并入队列,这个操作使得原本在队列头部的元素移到了队列尾部。
- 然后,弹出队列头部的元素,即栈的顶部元素,返回它。
4. `top(self) -> int`:获取栈顶元素但不弹出。如果栈为空,返回 `None`。具体操作如下:
- 如果栈不为空,通过循环将队列中除了最后一个元素外的所有元素出队列并入队列,这个操作使得原本在队列头部的元素移到了队列尾部。
- 然后,将队列头部的元素(栈顶元素)暂时存储在 `temp` 变量中,再将 `temp` 入队列,以恢复原本的队列状态。
- 最后,返回 `temp`,即栈的顶部元素。
5. `empty(self) -> bool`:检查栈是否为空。如果双端队列 `que` 为空,返回 `True`,表示栈为空;否则返回 `False`,表示栈不为空。