腐烂的橘子


题干

这题本质上考察的就是广度优先搜索。我们假设只有一个腐烂的橘子,这种情况比较好说明。那么我们从这个腐烂的橘子的上下左右四个方向开始BFS,每次遍历到一个新鲜的橘子,我们就把它腐烂。注意到BFS一般会借助队列来实现,那我刚开始肯定是把腐烂的橘子的位置加入队列,然后从队列中弹出并进行腐烂操作。等到队列为空时,我再来看看是否还存在新鲜的橘子,并据此输出答案。

但是这只是特殊情况,我们需要考虑一般情况,因为一般来说不会只有一个腐烂的橘子。那怎么办呢?我们建立一个超级源点就好了。首先,把格子中所有腐烂橘子的坐标全部加入队列中,这些位置本质上就是一个位置。至于次数,我们使用二维数组来完成处理,每遍历到一个新鲜橘子,我们就把最近腐烂橘子(也就是广度优先搜索的那个中心点)的值加上1作为其在二维数组中的位置的值,也就是次数。等到遍历完成后,这个次数一定是最少的,因为届时就没有新鲜橘子可以抵达了,这一点可以仔细想想。

代码:

package com.hw.test;

import java.util.LinkedList;
import java.util.Queue;

public class RottingOranges {
    private int[] dx = {1, 0, -1, 0};
    private int[] dy = {0, 1, 0, -1};
    private Queue<int[]> q = new LinkedList<>();
    public int orangesRotting(int[][] grid) {
        int ans = 0;
        boolean flag = false;
        int row = grid.length, col = grid[0].length;
        int[][] mat = new int[row][col];
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                if (grid[i][j] == 2) {
                    q.offer(new int[]{i, j});
                }
            }
        }
        while (!q.isEmpty()) {
            int[] cell = q.poll();
            int nx = cell[0], ny = cell[1];
            for (int i = 0; i < 4; ++i) {
                int mx = nx + dx[i];
                int my = ny + dy[i];
                if (mx >= 0 && mx < row && my >= 0 && my < col && grid[mx][my] == 1) {
                    mat[mx][my] = mat[nx][ny] + 1;
                    ans = mat[mx][my];
                    grid[mx][my] = 2;
                    q.offer(new int[]{mx, my});
                }
            }
        }
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                if (grid[i][j] == 1) {
                    flag = true;
                    break;
                }
            }
        }
        return flag ? -1 : ans;
    }
    public static void main(String[] args) {
        int[][] grid = {
                {2, 1, 1},
                {1, 1, 0},
                {0, 1, 1}
        };
        int ans = new RottingOranges().orangesRotting(grid);
        System.out.println(ans);
    }
}