腐烂的橘子
在给定的 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 。
思路一
function orangesRotting(grid) {
const m = grid.length;
const n = grid[0].length;
let freshOranges = 0;
const queue = [];
const directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
// 初始化
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] === 2) {
queue.push([i, j]);
} else if (grid[i][j] === 1) {
freshOranges++;
}
}
}
let minutes = 0;
while (queue.length > 0 && freshOranges > 0) {
const size = queue.length;
for (let i = 0; i < size; i++) {
const [r, c] = queue.shift();
for (const [dr, dc] of directions) {
const nr = r + dr;
const nc = c + dc;
if (nr >= 0 && nr < m && nc >= 0 && nc < n && grid[nr][nc] === 1) {
grid[nr][nc] = 2; // 橘子腐烂
freshOranges--; // 新鲜橘子数量减少
queue.push([nr, nc]); // 加入队列
}
}
}
minutes++; // 时间增加
}
return freshOranges === 0 ? minutes : -1;
}
讲解
腐烂的橘子问题(Rotting Oranges)涉及到在一个给定的网格中,某些单元格包含新鲜橘子(值为 1),某些单元格包含腐烂的橘子(值为 2),还有些单元格为空(值为 0)。腐烂的橘子会传染给相邻(上下左右)的新鲜橘子,使得它们在一分钟后也腐烂。任务是计算直到所有新鲜橘子都腐烂所需的分钟数,如果不可能则返回 -1。
- 初始化:创建一个队列 queue,用于存储腐烂橘子的位置。同时,计算总共有多少新鲜橘子。
- 广度优先搜索(BFS):从所有初始的腐烂橘子开始,使用 BFS 遍历网格。将所有初始的腐烂橘子位置加入队列,并开始 BFS 过程。
- 传播腐烂:在每一轮 BFS 中,从队列中取出腐烂橘子的位置,检查其四个相邻的单元格。如果相邻单元格中有新鲜橘子(值为 1),则将其标记为腐烂(值改为 2),并加入队列中等待下一轮传染。
- 更新时间:每完成一轮 BFS,表示所有能够被感染的新鲜橘子都已经变为腐烂状态,这时将时间加一。
- 检查是否全部腐烂:在 BFS 结束后,检查是否有新鲜橘子仍然存在。如果有,说明有些橘子永远无法腐烂,返回 -1。如果没有,返回经过的时间。