LeetCode | 994. 腐烂的橘子 | 网格 | BFS

LeetCode | 994. 腐烂的橘子

解题思路:

  • 同一时刻,烂橘子会同时开始传播,所以用深度遍历就不适用了。
  • 虽然是网格,但是烂橘子传播就像是树层序遍历到叶子结点,遍历每一层的时候,就需要时间+1,所以可以抽象成树的层序遍历,不断遍历到叶子结点所需要花费的时间。
  • 需要获得条件:新鲜橘子数量;初始烂橘子的队列。
  • 层序遍历循环的条件:烂橘子队列不为空 以及 还存在新鲜的橘子。
  • 遍历中需要执行:
    • 花费时间+1
    • 遍历当前队列中的烂橘子
    • 传播烂橘子。将烂橘子周围的新鲜橘子加入到烂橘子队列中,并将其变成烂橘子,并将新鲜橘子数量-1。
  • 返回条件:如果遍历完烂橘子队列了,还有新鲜橘子,那么就返回-1。否则,返回遍历整个烂橘子树的总时间。
class Solution {
    public int orangesRotting(int[][] grid) {
        int M = grid.length;
        int N = grid[0].length;
        int orangeNums = 0; // 新鲜橘子的数量
        int time = 0; // 所需要花费的时间`
        Queue<int[]> queue = new LinkedList<>(); // 存放烂橘子队列

        // 获得烂橘子的队列与新鲜橘子个数
        for (int x = 0; x < M; x++) {
            for (int y = 0; y < N; y++) {
                if (grid[x][y] == 2) {
                    queue.add(new int[]{x, y});
                } else if (grid[x][y] == 1) {
                    orangeNums++;
                }
            } // for.x
        } // for.x 

        // 开始层序遍历,传播烂橘子
        while (orangeNums > 0 && !queue.isEmpty()) { // 没有新鲜橘子 或者 队列为空了 -> 退出循环
            time++;
            int n = queue.size();
            while (n > 0) {
                n--; // 弹出了一个烂橘子了,队列循环-1
                // 获得烂橘子的坐标
                int[] rotten = queue.poll();
                int x = rotten[0];
                int y = rotten[1];
                
                // 传播腐烂
                // 上
                if (x - 1 >= 0 && grid[x - 1][y] == 1) {
                    orangeNums--;
                    grid[x - 1][y] = 2;
                    queue.add(new int[]{x - 1, y});
                }
                // 下
                if (x + 1 < M && grid[x + 1][y] == 1) {
                    orangeNums--;
                    grid[x + 1][y] = 2;
                    queue.add(new int[]{x + 1, y});
                }
                // 左
                if (y - 1 >= 0 && grid[x][y - 1] == 1) {
                    orangeNums--;
                    grid[x][y - 1] = 2;
                    queue.add(new int[] {x, y - 1});
                }
                // 右
                if (y + 1 < N && grid[x][y + 1] == 1) {
                    orangeNums--;
                    grid[x][y + 1] = 2;
                    queue.add(new int[] {x, y + 1});
                }
            } // while close

        } // while close
        
        return orangeNums > 0 ? -1 : time;
    } // orangesRotting
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值