理论基础
整体原则:创建两个stack去实现queue的“先进先出”原则。换句话讲,这是一个“负负得正”的操作。
1.push 方法: 使用 append 将元素添加到 stack_in。
2.pop 方法: 确保只有当 stack_out 为空时,元素才会从 stack_in 转移到 stack_out。使用 pop 从 3.stack_out 中移除并返回最后一个元素。
4.peek 方法: 与 pop 类似,但会返回 stack_out 的最后一个元素,而不会删除它。
5.empty 方法: 检查 stack_in 和 stack_out 是否为空,以确定队列是否为空。
易错点
1.self.stack_out.pop() 方法实际上是删除并返回 stack_out 列表的最后一个元素。然而,在 peek 方法中,我们并不想执行任何实际的 pop 操作。相反,我们应该只检索值而不删除它。
2.return not self.stack_in and not self.stack_out 表达的是队列是否为空的判断条件。它的意思是如果 stack_in 和 stack_out 都为空,则返回 True,表示队列为空;否则返回 False,表示队列不为空。
3.在 Python 中,`list` 类型的对象使用 `append` 方法来添加元素到列表的末尾。这是因为 Python 的列表是动态数组,`append` 方法是专门用来在数组末尾添加元素的。与之相比,在一些其他编程语言中,比如 Java 中的 `ArrayList` 或 C++ 中的 `std::vector`,通常会使用 `push_back` 方法来实现类似的功能,这个方法也是在数组末尾添加元素。因此,在这些语言中,你会看到类似于 `list.push_back(x)` 这样的用法。Python 的 `list` 对象并没有 `push` 方法,因为它并不是一个栈类别的数据结构。如果要实现栈的操作,可以使用 `list` 来模拟,但需要使用 `append` 和 `pop` 方法来模拟压栈和出栈的操作,而不是 `push`。
代码实现:
-push 操作的时间复杂度为 O(1),因为我们只是将元素添加到 stack_in 列表中。
-在最坏的情况下,即 stack_out 为空,我们需要将所有元素从 stack_in 转移到 stack_out,那么 pop 和 peek 操作的时间复杂度为 O(n)。不过,平均来说,pop 和 peek 操作的时间复杂度为 O(1),因为我们只是偶尔需要传输元素。
-MyQueue 类的空间复杂度为 O(n),其中 n 是队列中元素的数量。这是因为我们使用了两个栈来实现队列,这两个栈有可能存储队列中的所有元素。
class MyQueue(object):
#首先创建两个stack来实现‘先进先出’
def __init__(self):
self.stack_in = []
self.stack_out = []
def push(self, x):
"""
:type x: int
:rtype: None
"""
self.stack_in.append(x)
def pop(self):
"""
:rtype: int
"""
if not self.stack_out:
while self.stack_in:
self.stack_out.append(self.stack_in.pop())
return self.stack_out.pop()
def peek(self):
"""
:rtype: int
"""
if not self.stack_out:
while self.stack_in:
self.stack_out.append(self.stack_in.pop())
return self.stack_out[-1]
def empty(self):
"""
:rtype: bool
"""
return not self.stack_in and not self.stack_out
225. 用队列实现栈 (easy)
可以大家惯性思维,以为还要两个队列来模拟栈,其实只用一个队列就可以模拟栈了。
建议大家掌握一个队列的方法,更简单一些,可以先看视频讲解
题目链接/文章讲解/视频讲解:代码随想录
代码实现:
1.创建一个queue实现stack(进阶版):
from collections import deque
class MyStack(object):
def __init__(self):
self.queue = deque()
def push(self, x):
"""
:type x: int
:rtype: None
"""
self.queue.append(x)
def pop(self):
"""
:rtype: int
"""
if self.empty():
return None
for _ in range(len(self.queue) - 1):
self.queue.append(self.queue.popleft())
popped_value = self.queue.popleft()
return popped_value
def top(self):
"""
:rtype: int
"""
if self.empty():
return None
for _ in range(len(self.queue) - 1):
self.queue.append(self.queue.popleft())
top_value = self.queue.popleft()
self.queue.append(top_value)
return top_value
def empty(self):
"""
:rtype: bool
"""
return len(self.queue) == 0
2.创建两个queues(初级版):
from collections import deque
class MyStack(object):
def __init__(self):
self.queue_in = deque()
self.queue_out = deque()
def push(self, x):
"""
:type x: int
:rtype: None
"""
self.queue_in.append(x)
def pop(self):
"""
:rtype: int
"""
if self.empty():
return None
while len(self.queue_in) > 1:
self.queue_out.append(self.queue_in.popleft())
poped_val = self.queue_in.popleft()
# Swap queues
self.queue_in, self.queue_out = self.queue_out, self.queue_in
return poped_val
def top(self):
"""
:rtype: int
"""
if self.empty():
return None
while len(self.queue_in) > 1:
self.queue_out.append(self.queue_in.popleft())
# pop left
top_val = self.queue_in.popleft()
# Move the top element to queue_out
self.queue_out.append(top_val)
# Swap queues
self.queue_in, self.queue_out = self.queue_out, self.queue_in
return top_val
def empty(self):
"""
:rtype: bool
"""
return len(self.queue_in) == 0