当前位置: 首页 > news >正文

【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) 问题。

核心步骤如下:

  1. 将所有腐烂橘子作为起点入队(因为它们会同时开始扩散)。

  2. 每一轮 BFS 代表一分钟,处理队列中的所有元素,并尝试腐蚀四周新鲜橘子。

  3. 如果有新鲜橘子被腐蚀,则将它们加入下一轮队列。

  4. 统计每轮是否真的腐蚀了新橘子,只有在扩散发生时才增加时间。

  5. 最后判断是否还有剩余新鲜橘子,如果有则返回 -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 控制时间);

的全面掌握。掌握之后,你可以轻松应对更多类似题目,比如:

  • 火焰蔓延问题

  • 岛屿感染问题

  • 最短路径带时间传染传播


如果你觉得这篇博客对你有帮助,欢迎点赞、收藏和评论交流 
更多图解题解,欢迎关注我!

相关文章:

  • Master节点重启k8s集群崩溃解决办法
  • AGI大模型(10):prompt逆向-巧借prompt
  • Windows 系统下安装 Docker
  • 构建网络 练习题三道
  • idea快捷键 Spring endpoint actions in the editor
  • Vue自定义指令最佳实践教程
  • 2022年蓝桥杯第十三届CC++大学B组真题及代码
  • Jmeter如何使用MD5进行加密?
  • 界面控件DevExpress WPF v25.1新功能预览 - AI功能增强
  • 大厂算法面试 7 天冲刺:第6天-树与图深度剖析——高频算法面试题 Java 实战
  • oracle WAIT 和 NOWAIT
  • 基于开源链动 2+1 模式 AI 智能名片 S2B2C 商城小程序的社群团购品牌命名策略研究
  • Kotlin 类委托深入解析:以 MMKV 为例看委托机制在 Android 中的巧妙应用
  • 2025年渗透测试面试题总结- 某腾讯科恩实验室实习扩展 一面(题目+回答)
  • 手搓MNIST数据集识别神经网络
  • 【mongodb】mongodb的字段类型
  • REST 方法
  • 数据分析参考架构详解
  • 算法 | 基于灰狼优化算法求解带时间窗的车辆路径问题(VRPTW)研究(附matlab代码)
  • 图像处理中的高斯金字塔与直方图分析
  • h5网站建设文章/吉林seo网络推广
  • 数据库型网站/企业网络营销推广案例
  • 网站结构怎么做/百度信息流广告怎么投放
  • wordpress影视主题下载/武汉seo优化代理
  • 做网站只解析www的会怎么样/郑州网站策划
  • 外贸公司网站推广/微信公众号推广方法有哪些