【Leetcode 994】腐烂的橘子 - 多源 BFS 解题思路与 Java 实现详解
当然可以!下面是一篇围绕你提供的代码撰写的博客文章,包含 题目背景、解题思路、代码解析、优化建议 等模块,适合发布在 CSDN、掘金、博客园等技术平台。
题目描述
在一个
m x n
的网格中,网格中的每个单元格可以有以下三个值之一:
-
0
表示空单元格; -
1
表示新鲜橘子; -
2
表示腐烂橘子。
每分钟,腐烂的橘子会让上下左右相邻的新鲜橘子变成腐烂。
请返回直到没有新鲜橘子为止所必须经过的最小分钟数。如果不可能让所有橘子都腐烂,返回 -1。
示例输入:
grid = [
[2,1,1],
[1,1,0],
[0,1,1]
]
输出: 4
解题思路:多源 BFS
这是一道典型的 多源广度优先搜索(Multi-Source BFS) 问题。
核心步骤如下:
-
将所有腐烂橘子作为起点入队(因为它们会同时开始扩散)。
-
每一轮 BFS 代表一分钟,处理队列中的所有元素,并尝试腐蚀四周新鲜橘子。
-
如果有新鲜橘子被腐蚀,则将它们加入下一轮队列。
-
统计每轮是否真的腐蚀了新橘子,只有在扩散发生时才增加时间。
-
最后判断是否还有剩余新鲜橘子,如果有则返回 -1。
Java 代码实现
class Solution {
// 上、下、左、右四个方向
static int[][] dir = {{1,0}, {-1,0}, {0,1}, {0,-1}};
public int orangesRotting(int[][] grid) {
int n = grid.length;
int m = grid[0].length;
Queue<int[]> q = new LinkedList<>();
int cont = 0; // 新鲜橘子数量
// 初始化:统计新鲜橘子 & 把所有腐烂橘子加入队列
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 2) {
q.add(new int[]{i, j});
} else if (grid[i][j] == 1) {
cont++;
}
}
}
// 没有新鲜橘子,直接返回 0
if (cont == 0) return 0;
int ans = 0;
while (!q.isEmpty()) {
int size = q.size();
boolean flag = false; // 本轮是否有橘子被腐蚀
for (int i = 0; i < size; i++) {
int[] cur = q.remove();
for (int j = 0; j < 4; j++) {
int curX = cur[0] + dir[j][0];
int curY = cur[1] + dir[j][1];
// 边界检查
if (curX >= 0 && curY >= 0 && curX < n && curY < m) {
if (grid[curX][curY] == 1) {
grid[curX][curY] = 2; // 腐烂该橘子
flag = true;
q.add(new int[]{curX, curY});
cont--; // 减少新鲜橘子计数
}
}
}
}
// 如果这一轮有橘子被腐蚀,则时间+1
if (flag) {
ans++;
}
}
// 如果还有没腐烂的新鲜橘子,返回 -1,否则返回所需时间
return cont > 0 ? -1 : ans;
}
}
为什么只在有橘子腐蚀时才 ans++
?
我们不希望在 BFS 最后一轮(已经没有可腐蚀的橘子)时仍然增加时间,因此用了一个 flag
来判断本轮是否真的发生腐蚀,从而确保 ans
的准确性。
测试用例
输入:
[[2,1,1],
[1,1,0],
[0,1,1]]
输出:4
输入:
[[2,1,1],
[0,1,1],
[1,0,1]]
输出:-1
输入:
[[0,2]]
输出:0
时间复杂度和空间复杂度分析
-
时间复杂度:
O(m * n)
,每个位置最多被访问一次。 -
空间复杂度:
O(m * n)
,队列最多同时存储所有橘子的位置。
可优化点
-
可以将
int[]
替换成自定义类或结构体,提升可读性; -
可以使用
Deque
替代Queue
实现双向 BFS 结构; -
对于特别大的数据,还可以考虑提前剪枝。
总结
这道题作为 BFS 的经典题目,锻炼了你对于:
-
多源 BFS 的理解;
-
BFS 分层处理(每一层表示时间);
-
细节边界判断(新鲜橘子统计、flag 控制时间);
的全面掌握。掌握之后,你可以轻松应对更多类似题目,比如:
-
火焰蔓延问题
-
岛屿感染问题
-
最短路径带时间传染传播
如果你觉得这篇博客对你有帮助,欢迎点赞、收藏和评论交流
更多图解题解,欢迎关注我!