LeetCode 0994 - 腐烂的橘子
📖 题目描述
在给定的
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 。
核心问题:如何在每分钟内模拟腐烂橘子的传播过程,并判断所有新鲜橘子是否都能在有限时间内被腐烂,如果可以则返回所需的最小分钟数,否则返回 -1。
💡 解题思路
🔎 思路概览(一句话总结)
使用多源广度优先搜索(BFS)从所有腐烂橘子同时开始扩散,逐层传播腐烂状态,直到无法继续或所有新鲜橘子被腐烂。
- 问题建模为图传播问题:
- 将网格视为一个图,橘子之间的传播关系可以看作图中结点之间的边(上下左右相邻)。
- 腐烂橘子的扩散过程等价于图中的逐层 BFS 遍历,每一层代表一分钟。
- 使用多源 BFS:
- 所有初始的腐烂橘子同时开始传播,相当于图中多个起点的 BFS。
- 每轮 BFS 扩展一步,相邻的新鲜橘子腐烂并入队。
- 逐步推进时间:
- 每完成一层 BFS 扩展(即当前队列中的所有橘子处理完),分钟数加一。
- 直到没有可传播的橘子或所有新鲜橘子腐烂完。
- 终止条件与结果判断:
- 如果在 BFS 结束后还有未被腐烂的新鲜橘子,说明存在无法被感染的孤立区域,返回
-1
。 - 否则,返回传播所经历的分钟数。
- 如果在 BFS 结束后还有未被腐烂的新鲜橘子,说明存在无法被感染的孤立区域,返回
利用 BFS 的分层特性自然模拟“时间的流逝”,将局部传播扩展为全局感染。
🧩 解法详解
- 将所有初始为
2
的腐烂橘子位置加入队列,作为 BFS 的起点(多源 BFS); - 同时统计初始为
1
的数量(新鲜橘子数); - 每进行一轮 BFS (每分钟),将队列中所有腐烂橘子对四个方向进行拓展:
- 如果发现邻接的新鲜橘子`grif[x][y] == 1’:
- 腐烂它(变为 2),并加入队列;
- 新鲜橘子数减 1.
- 如果发现邻接的新鲜橘子`grif[x][y] == 1’:
- 直到队列为空,统计所需的分钟数;
- 如果最后仍有新鲜橘子存在,返回
-1
,否则返回分钟数。
📈 复杂度分析
m
为网格行数,n
为列数。
- 时间复杂度:
O(m * n)
,在 BFS 过程中,每个格子最多访问一次(因为橘子一旦腐烂,不会再次入队)。每个腐烂的句子在上下左右最多拓展 4 次邻居,但不会重复,因此最多处理m * n
个格子。 - 空间复杂度:
O(m * n)
,队列中最多同时存储所有格子的坐标,最坏情况是所有橘子都腐烂入队。
✅ 代码实现
import java.util.LinkedList; |
🔁 拓展与变形
📚 相关题目推荐
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 SunnyALion!
评论