题解 | 【python3】队列操作
【模板】队列操作
https://www.nowcoder.com/practice/1137c8f6ffac4d5d94cc1b0cb08723f9
import sys
from collections import deque
input = sys.stdin.readline
class Solution:
def __init__(self):
self.q = deque()
def solve(self, arr):
result = None
if arr[0] == 1:
self.q.append(arr[1])
elif arr[0] == 2:
if self.q:
self.q.popleft()
else:
print("ERR_CANNOT_POP")
elif arr[0] == 3:
if self.q:
print(self.q[0])
else:
print("ERR_CANNOT_QUERY")
elif arr[0] == 4:
print(len(self.q))
if __name__ == "__main__":
sol = Solution()
n = int(input()) # 第一行表示输入行数
for _ in range(n):
arr = list(map(int, input().split()))
sol.solve(arr)
Python 模板题:队列操作
这道题是一个典型的队列模拟题。
题目要求维护一个空队列,并支持以下 4 种操作:
1 x:将整数x入队2:如果队列非空,删除队头元素;否则输出ERR_CANNOT_POP3:查询并输出队头元素;如果队列为空,输出ERR_CANNOT_QUERY4:输出当前队列中的元素个数
这类题的本质就是:按照题意模拟数据结构操作。
一、为什么用 deque
Python 里实现队列,最适合使用 collections.deque。
因为:
- 队尾插入:
append() - 队头删除:
popleft()
时间复杂度都比较优秀。
如果用普通列表 list 去写队列,虽然也能写,但 pop(0) 会导致后面的元素整体前移,效率较低。
所以队列题的标准写法一般都是:
from collections import deque q = deque()
二、解题思路
我们只需要维护一个队列 q。
遍历每一条操作指令:
- 如果是 1 x,就执行 q.append(x)
- 如果是 2:队列非空:q.popleft()队列为空:输出 ERR_CANNOT_POP
- 如果是 3:队列非空:输出 q[0]队列为空:输出 ERR_CANNOT_QUERY
- 如果是 4:输出 len(q)
三、class 写法
这种写法更适合你后面刷模板题时统一风格,也方便把“数据结构”和“操作逻辑”封装到一起。
代码
import sys
from collections import deque
input = sys.stdin.readline
class Solution:
def __init__(self):
self.q = deque()
def solve(self, arr):
if arr[0] == 1:
self.q.append(arr[1])
elif arr[0] == 2:
if self.q:
self.q.popleft()
else:
print("ERR_CANNOT_POP")
elif arr[0] == 3:
if self.q:
print(self.q[0])
else:
print("ERR_CANNOT_QUERY")
elif arr[0] == 4:
print(len(self.q))
if __name__ == "__main__":
sol = Solution()
n = int(input())
for _ in range(n):
arr = list(map(int, input().split()))
sol.solve(arr)
写法说明
1. 初始化队列
self.q = deque()
表示创建一个空队列。
2. 入队操作
self.q.append(arr[1])
因为输入 1 x 会被读成一个列表,比如:
[1, 10]
所以 arr[1] 就是要插入的值。
3. 出队操作
self.q.popleft()
表示删除队头元素。
注意这里一定要先判断队列是否为空:
if self.q:
空队列时不能直接 popleft(),否则会报错。
4. 查询队头
print(self.q[0])
队头元素就是下标 0 的位置。
同样也要先判断是否为空。
5. 输出队列长度
print(len(self.q))
四、简单写法
如果你不想写 class,其实这题直接用一个队列变量就可以了,代码会更短。
代码
import sys
from collections import deque
input = sys.stdin.readline
q = deque()
n = int(input())
for _ in range(n):
arr = list(map(int, input().split()))
if arr[0] == 1:
q.append(arr[1])
elif arr[0] == 2:
if q:
q.popleft()
else:
print("ERR_CANNOT_POP")
elif arr[0] == 3:
if q:
print(q[0])
else:
print("ERR_CANNOT_QUERY")
elif arr[0] == 4:
print(len(q))
五、两种写法怎么选
1. class 写法适合什么时候
适合你:
- 刷模板题时想保持统一风格
- 后面还会继续写栈、队列、链表、堆等题目
- 想把“结构”和“操作”封装起来
优点是结构清晰,便于复用。
2. 简单写法适合什么时候
适合你:
- 只想快速通过这道题
- 题目逻辑非常简单
- 想让代码尽量短
优点是直接、简洁。
六、这题的易错点
易错点 1:查询空队列时输出写错
这题最容易错的不是队列逻辑,而是错误信息。
要严格区分:
2空队列:ERR_CANNOT_POP3空队列:ERR_CANNOT_QUERY
很多人会把查询空队列时也写成 ERR_CANNOT_POP,这样样例可能过,但提交会错。
易错点 2:不要用 list.pop(0)
错误示例:
q = [] q.append(x) q.pop(0)
虽然逻辑上也像队列,但效率不如 deque。
标准写法应为:
from collections import deque q = deque() q.append(x) q.popleft()
易错点 3:输入要按整数读
因为这题操作是数字形式:
1 x234
所以用:arr = list(map(int, input().split()))
最方便。
七、复杂度分析
设总操作数为 n。
- 每次入队:
O(1) - 每次出队:
O(1) - 查询队头:
O(1) - 查询长度:
O(1)
所以总时间复杂度为:O(n)
空间复杂度为:O(n)
最坏情况下所有元素都在队列中。
八、总结
这道题就是一个标准的队列模拟题,核心只有两点:
- 用
deque来维护队列 - 按题意处理空队列时的输出
你可以直接记住下面这几个操作:
from collections import deque q = deque() q.append(x) # 入队 q.popleft() # 出队 q[0] # 队头 len(q) # 队列长度
如果你要的话,我下一条可以继续给你整理成你常用的那种“博客模板风格”,比如:
- 题目描述
- 思路分析
- 代码
- 易错点
- 模板总结
更像一篇正式题解。
查看4道真题和解析