题目描述
在给定的 m x n
网格 grid
中,每个单元格可以有以下三个值之一:
值 0
代表空单元格;
值 1
代表新鲜橘子;
值 2
代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1
。
示例 1:
输入: grid = [[2,1,1],[1,1,0],[0,1,1]]
输出: 4
示例 2:
输入: grid = [[2,1,1],[0,1,1],[1,0,1]]
输出: -1
解释: 左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个方向上。
示例 3:
输入: grid = [[0,2]]
输出: 0
解释: 因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
提示:
- m == grid.length
- n == grid[i].length
- 1 <= m, n <= 10
- grid[i][j] 仅为0、1 或 2
代码及注释
func orangesRotting(grid [][]int) int {
m, n := len(grid), len(grid[0]) // 获取网格的行数和列数
queue := [][2]int{} // 定义一个队列用于存储腐烂的橘子的坐标
// 初始化队列,将所有腐烂的橘子的坐标加入队列
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == 2 {
queue = append(queue, [2]int{i, j})
}
}
}
minites := 0 // 初始化分钟数
for len(queue) > 0 { // 当队列不为空时循环
length := len(queue)
for i := 0; i < length; i++ {
current := queue[0] // 获取队首腐烂的橘子的坐标
queue = queue[1:] // 弹出队首元素
// 检查上下左右四个方向的橘子
if current[0] - 1 >= 0 && grid[current[0] - 1][current[1]] == 1 {
grid[current[0] - 1][current[1]] = 2 // 将新鲜的橘子标记为腐烂
queue = append(queue, [2]int{current[0] - 1, current[1]}) // 将新腐烂的橘子的坐标加入队列
}
if current[0] + 1 < m && grid[current[0] + 1][current[1]] == 1 {
grid[current[0] + 1][current[1]] = 2
queue = append(queue, [2]int{current[0] + 1, current[1]})
}
if current[1] - 1 >= 0 && grid[current[0]][current[1] - 1] == 1 {
grid[current[0]][current[1] - 1] = 2
queue = append(queue, [2]int{current[0], current[1] - 1})
}
if current[1] + 1 < n && grid[current[0]][current[1] + 1] == 1 {
grid[current[0]][current[1] + 1] = 2
queue = append(queue, [2]int{current[0], current[1] + 1})
}
}
if len(queue) > 0 {
minites++
}
}
// 检查是否还有新鲜的橘子
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == 1 {
return -1 // 如果有新鲜的橘子,则返回 -1
}
}
}
return minites // 返回分钟数
}
代码解释
-
初始化队列:遍历整个网格,将所有腐烂的橘子的坐标加入队列。
for i := 0; i < m; i++ { for j := 0; j < n; j++ { if grid[i][j] == 2 { queue = append(queue, [2]int{i, j}) } } }
-
BFS遍历:使用BFS遍历队列中的腐烂的橘子,并将与之相邻的新鲜橘子标记为腐烂。
for len(queue) > 0 { length := len(queue) for i := 0; i < length; i++ { current := queue[0] queue = queue[1:] // 检查上下左右四个方向的橘子 if current[0] - 1 >= 0 && grid[current[0] - 1][current[1]] == 1 { grid[current[0] - 1][current[1]] = 2 queue = append(queue, [2]int{current[0] - 1, current[1]}) } if current[0] + 1 < m && grid[current[0] + 1][current[1]] == 1 { grid[current[0] + 1][current[1]] = 2 queue = append(queue, [2]int{current[0] + 1, current[1]}) } if current[1] - 1 >= 0 && grid[current[0]][current[1] - 1] == 1 { grid[current[0]][current[1] - 1] = 2 queue = append(queue, [2]int{current[0], current[1] - 1}) } if current[1] + 1 < n && grid[current[0]][current[1] + 1] == 1 { grid[current[0]][current[1] + 1] = 2 queue = append(queue, [2]int{current[0], current[1] + 1}) } } if len(queue) > 0 { minites++ } }
-
检查新鲜橘子:在BFS遍历结束后,检查网格中是否还有新鲜的橘子。
for i := 0; i < m; i++ { for j := 0; j < n; j++ { if grid[i][j] == 1 { return -1 } } } return minites
这样的做法是基于BFS的思路,每一轮BFS都表示了一分钟的时间,直到没有新的橘子可以被腐烂为止。