一、队列入门
1、滑动窗口:
示例:
输入:
["RecentCounter", "ping", "ping", "ping", "ping"]
[[], [1], [100], [3001], [3002]]
输出:
[null, 1, 2, 3, 3]
解释:
RecentCounter recentCounter = new RecentCounter();
recentCounter.ping(1); // requests = [1],范围是 [-2999,1],返回 1
recentCounter.ping(100); // requests = [1, 100],范围是 [-2900,100],返回 2
recentCounter.ping(3001); // requests = [1, 100, 3001],范围是 [1,3001],返回 3
recentCounter.ping(3002); // requests = [1, 100, 3001, 3002],范围是 [2,3002],返回 3
代码框架:
class RecentCounter:
def __init__(self):
def ping(self, t: int) -> int:
# Your RecentCounter object will be instantiated and called as such:
# obj = RecentCounter()
# param_1 = obj.ping(t)
思想:
我们只会考虑最近 3000 毫秒到现在的
ping
数,因此我们可以使用队列存储这些ping
的记录。当收到一个时间t
的ping
时,我们将它加入队列,并且将所有在时间t - 3000
之前的ping
移出队列。
实现:
class RecentCounter:
def __init__(self):
self.q = collections.deque()
def ping(self, t: int) -> int:
self.q.append(t)
while self.q[0] < t-3000:
self.q.popleft()
return len(self.q)
# Your RecentCounter object will be instantiated and called as such:
# obj = RecentCounter()
# param_1 = obj.ping(t)
2、广度优先搜索:
代码框架:
class Solution:
def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:
思想:
在一个图中,能从一个点出发求这种最短距离的方法很容易想到就是 BFS,BFS 的名称是广度优先遍历,即把周围这一圈搜索完成之后,再搜索下一圈,是慢慢扩大搜索范围的。
图左边是BFS,按照层进行搜索;图右边是 DFS,先一路走到底,然后再回头搜索。
故直接套用广度优先搜索的框架:
class Solution:
def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
M, N = len(matrix), len(matrix[0])
queue = collections.deque()
visited = [[0] * N for _ in range(M)]
res = [[0] * N for _ in range(M)]
for i in range(M):
for j in range(N):
if matrix[i][j] == 0:
queue.append((i, j))
visited[i][j] = 1
dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
step = 0
while queue:
size = len(queue)
for i in range(size):
x, y = queue.popleft()
if matrix[x][y] == 1:
res[x][y] = step
for dx, dy in dirs:
newx, newy = x + dx, y + dy
if newx < 0 or newx >= M or newy < 0 or newy >= N or visited[newx][newy] == 1:
continue
queue.append((newx, newy))
visited[newx][newy] = 1
step += 1
return res