LeetCode 994. 腐烂的橘子 多源BFS题解,又一道多源BFS,熟悉实现多源BFS。
994. 腐烂的橘子#
https://leetcode.cn/problems/rotting-oranges/
在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:
- 值 0 代表空单元格;
- 值 1 代表新鲜橘子;
- 值 2 代表腐烂的橘子。
- 每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。
BFS+四处发散#
关于多源BFS,参考 LeetCode 1162. 地图分析 BFS四处发散题解 。
本题思路较 1162,整体一致,细节方面,需多维护一个新鲜橘子数量,用来判定-1
的情况。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
/**
* 思路:
* 从腐烂的橘子开始,多源BFS扩散,一直扩散到空位或者边界即可
* 使用一个变量来维护最大距离
*/
public int orangesRotting(int[][] grid) {
// 666表示已经访问过了
int m = grid.length;
int n = grid[0].length;
Queue<int[]> pointQ = new ArrayDeque<>();
int freshCnt = 0;
for (int row = 0; row < m; row++) {
for (int col = 0; col < n; col++) {
if (grid[row][col] == 2) {
pointQ.offer(new int[]{row, col});
grid[row][col] = 666;
}
if (grid[row][col] == 1) {
freshCnt++;
}
}
}
int minutes = 0;
int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
while (!pointQ.isEmpty() && freshCnt > 0) {
int size = pointQ.size();
for (int i = 0; i < size; i++) {
int[] point = pointQ.poll();
int x = point[0];
int y = point[1];
for (int[] direction : directions) {
int newX = x + direction[0];
int newY = y + direction[1];
if (!inArea(newX, m) || !inArea(newY, n) || grid[newX][newY] == 666 || grid[newX][newY] == 0) {
continue;
}
// 新鲜橘子变腐烂,同时标记访问状态
grid[newX][newY] = 666;
pointQ.offer(new int[]{newX, newY});
// 某一轮过来的时候可能已经没有新鲜橘子了,此时判断下状态再计数
freshCnt--;
}
}
minutes++;
}
return freshCnt > 0 ? -1 : minutes;
}
private boolean inArea(int x, int m) {
return x >= 0 && x < m;
}
|
复杂度分析#
根据队列的操作,每个节点入队一次,出队一次,整个规模为矩阵数据量。
时间复杂度:O(m*n)
。
访问状态没有使用额外空间,而pointQ
最多一次可以发散四个节点,不考虑常数阶,空间复杂度O(1)
。
Ref#