在给定的
m x n网格grid中,每个单元格可以有以下三个值之一:
- 值
0代表空单元格- 值
1代表新鲜橘子;- 值
2代表腐烂的橘子。每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回
-1。
解法 bfs扩展
思路
我刚开始的想法是和岛屿数量一样,去给他沉没掉,结果发现并不行,如果存在多个腐烂的橘子,它的腐烂传递应该是相同开始的。
所以这就不能使用 dfs 去解答,但是扩展的思路可以借鉴,如果当前橘子是腐烂的,那么它的上下左右的新鲜橘子都会腐烂,就是相当于向四个方向扩展。
那么问题来了,如何去定义时间呢?就是队列的层数,每腐烂完一层,时间自增。
还有额外的问题:
- 队列遍历完毕,如果还存在新鲜橘子,直接返回
-1 - 全都是新鲜的橘子,要返回
0,说明结果要从0开始 - 所有的橘子都腐烂完,返回
bfs层数减一
代码
function orangesRotting(grid: number[][]): number {
const m = grid.length;
const n = grid[0].length;
const queue = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] === 2) {
queue.push([i, j]);
}
}
}
const setRotten = (r, c) => {
if (r < 0 || c < 0 || r >= m || c >= n || grid[r][c] !== 1) return;
grid[r][c] = 2;
queue.push([r, c]);
}
let result = 0;
while (queue.length) {
result++;
let size = queue.length;
while (size--) {
const [i, j] = queue.shift();
setRotten(i + 1, j);
setRotten(i - 1, j);
setRotten(i, j + 1);
setRotten(i, j - 1);
}
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] === 1) {
return - 1;
}
}
}
if (result === 0) {
return 0;
}
return result - 1;
};
时空复杂度
时间复杂度:O(mn)
空间复杂度:O(mn)