题目描述
在给定的网格中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。
返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1
解题思路
BFS广度优先搜索
用队列实现搜索,很像二叉树的层次遍历过程。
首先起始节点压入队列,然后当这个节点被推出队列,他的所有邻接点就得马上进入队列中,然后这样一直重复下去,直到队列空了。
这期间,我们可以把自己的实际问题‘放入’出队入队这一活动中,实现我们的算法
BFS主要用来寻找最短路径
从某一点出发,加入队列,然后当这个点出队列,则马上把它的所有邻点加入队列
重复的做这个过程,直到所有点遍历完在此过程中可以有一些终止条件,可用来寻找最短距离/我们想要的目的
这道题的主要思路:
-
一开始,我们找出所有腐烂的橘子,将它们放入队列,作为第0层的结点。
-
然后进行BFS遍历,每个结点的相邻结点可能是上下左右四个方向的结点,注意判断结点位于网格边界的特殊情况
-
由于可能存在无法被污染的橘子,我们需要记录新鲜橘子的数量。在BFS中,每遍历到一个橘子(污染了一个橘子),就将新鲜橘子的数量减一。如果BFS结束后这个数量仍未减为零,说明存在无法被污染的橘子。
代码:
class Solution:
def orangesRotting(self, grid):
"""
:param grid:List[List[int]]
:return: int
"""
M = len(grid)
N = len(grid[0])
queue = []
# 新鲜橘子数
count = 0
for r in range(M):
for c in range(N):
if grid[r][c] == 1:
count += 1
elif grid[r][c] == 2:
queue.append((r, c))
minute = 0
while count > 0 and len(queue) > 0:
minute += 1
n = len(queue)
for i in range(n):
r, c = queue.pop(0)
if r - 1 >= 0 and grid[r - 1][c] == 1:
grid[r - 1][c] = 2
count -= 1
queue.append((r - 1, c))
if r + 1 < M and grid[r + 1][c] == 1:
grid[r + 1][c] = 2
count -= 1
queue.append((r + 1, c))
if c - 1 >= 0 and grid[r][c - 1] == 1:
grid[r][c - 1] = 2
count -= 1
queue.append((r, c - 1))
if c + 1 < N and grid[r][c + 1] == 1:
grid[r][c + 1] = 2
count -= 1
queue.append((r, c + 1))
if count > 0:
return -1
else:
return minute
Reference: