LeetCode 232.用栈实现队列
题目链接
思路
使用两个栈来表示队列的先进先出。入栈和入队列是一样的,但是出栈的顺序和出队列是相反的,所以要把入栈的元素按顺序全部放在出栈的栈里(要注意放入的顺序是12345,放进out栈的顺序是54321,这样出栈的顺序就是12345,这样会方便从out最后的位置进出元素)
class MyQueue:
def __init__(self):
self.stack_in = []
self.stack_out = []
def push(self, x: int) -> None:
self.stack_in.append(x)
def pop(self) -> int:
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:
x = self.pop()
self.stack_out.append(x)
return x
def empty(self) -> bool:
if self.stack_in or self.stack_out: #只要in或out有元素,就说明队列不为空
return False
else:
return True
# 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()
反思
栈和队列的基本操作,push pop empty peek等,这道题可以理解两种数据结构的基本思想
LeetCode 225. 用队列实现栈
题目链接
思路
根据栈模拟队列的方式,本题也可以直接使用两个队列的方式模拟一个栈,思路:一个队列用来存放数据,当需要有元素n出栈,队列1取出前面n-1个元素放入队列2,在pop队列1中的元素n
(双队列代码如下:)
from collections import deque
class MyStack:
def __init__(self):
#用list可以,但是在使用pop(0)的时候时间复杂度为O(n),deque是一个双端队列,有append和appendleft,pop和popleft
self.queue1 = deque()
self.queue2 = deque()
def push(self, x: int) -> None:
self.queue1.append(x)
def pop(self) -> int: #popleft默认拿左边的元素,pop默认拿右边的元素
#首先判断队列部不为空
if self.empty():
return None
#把n-1的数据放进去
for i in range(len(self.queue1)-1):
self.queue2.append(self.queue1.popleft())
#直接把队列1和2互换,队列1就一直表示栈的内容,用2做备份
self.queue1, self.queue2 = self.queue2, self.queue1
return self.queue2.popleft()
def top(self) -> int:
#取出栈顶元素
"""x = self.pop()
self.queue1.append(x)
return x"""
return self.queue1[-1]
def empty(self) -> bool:
"""if self.queue1: #因为只有1会存数据,2只是备份,所以判断1即可
return False
else:
return True"""
return len(self.queue1) == 0
# Your MyStack object will be instantiated and called as such:
# obj = MyStack()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.top()
# param_4 = obj.empty()
更简便的思想是使用一个队列即可。思路是把n-1的元素取出然后放到此队列的末尾,这样头元素就是n
(单队列代码如下:)
from collections import deque
class MyStack:
def __init__(self):
self.queue = deque()
def push(self, x: int) -> None:
self.queue.append(x)
def pop(self) -> int:
if self.empty():
return None
#把n-1的数据放到末尾(仅此处与双队列不同)
n = len(self.queue)
for i in range(n-1):
self.queue.append(self.queue.popleft())
return self.queue.popleft()
def top(self) -> int:
if self.empty():
return None
return self.queue[-1]
def empty(self) -> bool:
return len(self.queue) == 0
反思
今天的内容比较偏基础,主要是通过两者互相表示,熟悉起来栈和队列的基本性质,包括push pop top/peek empty判断等,需要注意的点就是在做任何操作前,一定要注意栈/队列本身是否为空,避免出现对空栈/空队列进行操作