【图论】Leetcode 994. 腐烂的橘子【中等】

腐烂的橘子

在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:

  • 值 0 代表空单元格;
  • 值 1 代表新鲜橘子;
  • 值 2 代表腐烂的橘子。
    每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。

返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。

示例1:

输入 :grid = [[2,1,1],[1,1,0],[0,1,1]]
输出: 4

解题思路

使用广度优先搜索(BFS)算法来模拟腐烂的橘子的传播过程。
PS: 广度优先搜索(BFS)算法一般使用
Queue queue = new LinkedList<>();
搭配 while(!queue.isEmpty())来实现
因为队列的先进先出(FIFO)特性恰好符合 BFS 的搜索顺序。

  • 1、遍历整个网格,将腐烂的橘子的坐标加入队列,并统计新鲜橘子的数量。
  • 2、在队列不为空的情况下,从队列中取出腐烂的橘子,将其周围未腐烂的橘子腐烂,并将其坐标加入队列。
  • 3、每次从队列中取出橘子时,时间变量加一。
  • 4、在每次遍历完整个队列时,检查是否还有新鲜橘子没有被腐烂。
  • 如果有,则返回 -1。
  • 如果没有,则返回时间变量减一,因为最后一个橘子腐烂不需要再等待一分钟。

Java实现

java 复制代码
public class RottingOranges {
    public int orangesRotting(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int freshOranges = 0; // 记录新鲜橘子的数量
        Queue<int[]> queue = new LinkedList<>(); // 用于存储腐烂的橘子的位置

        // 统计新鲜橘子的数量,并将腐烂的橘子加入队列
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    freshOranges++;
                } else if (grid[i][j] == 2) {
                    queue.offer(new int[]{i, j});
                }
            }
        }

        int minutes = 0; // 记录经过的分钟数
        int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 上下左右四个方向

        // 开始进行 BFS,直到队列为空或者没有新鲜橘子为止
        while (!queue.isEmpty() && freshOranges > 0) {
            int size = queue.size();
            //当前腐烂的桔子
            for (int i = 0; i < size; i++) {
                int[] curr = queue.poll();
                //计算上下左右腐烂的桔子
                for (int[] dir : directions) {
                    int newX = curr[0] + dir[0];
                    int newY = curr[1] + dir[1];
                    if (newX >= 0 && newX < m && newY >= 0 && newY < n && grid[newX][newY] == 1) {
                        grid[newX][newY] = 2; // 标记为腐烂的橘子
                        queue.offer(new int[]{newX, newY});
                        freshOranges--; // 每腐烂一个橘子,新鲜橘子数量减一
                    }
                }
            }
            minutes++; // 经过一分钟
        }

        return freshOranges == 0 ? minutes : -1;
    }

    public static void main(String[] args) {
        RottingOranges oranges = new RottingOranges();
        int[][] grid = {
            {2, 1, 1},
            {1, 1, 0},
            {0, 1, 2}
        };
        System.out.println("Minimum minutes required: " + oranges.orangesRotting(grid));
    }
}

时间空间复杂度

  • 时间复杂度:O(m * n),其中 m 和 n 分别是网格的行数和列数,因为需要遍历整个网格。

  • 空间复杂度:O(m * n),在最坏的情况下,队列的大小可能会达到网格中所有新鲜橘子的数量,因此空间复杂度是 O(m * n)。

相关推荐
迟來北风31 分钟前
idea找不到或无法加载主类怎么解决
java·spring boot·intellij-idea
qq_3384323733 分钟前
IntelliJ IDEA远程开发代理远程服务器端口(免费内网穿透)
java·ide·intellij-idea·远程开发
南宫生2 小时前
力扣动态规划-19【算法学习day.113】
java·学习·算法·leetcode·动态规划
优人ovo2 小时前
基于JMX实现消息队列监控
java·kafka
fly spider2 小时前
每日 Java 面试题分享【第 20 天】
java·开发语言·面试·io
zhyhgx2 小时前
Maven
java·开发语言·maven
纪元A梦2 小时前
Java设计模式:行为型模式→状态模式
java·设计模式·状态模式
苏-言2 小时前
Maven全解析:Maven 进阶
java·maven
暮色初上_2 小时前
700. 二叉搜索树中的搜索
c++·leetcode·回归算法