[LeetCode]腐烂的橘子

腐烂的橘子

题目链接
https://leetcode-cn.com/problems/rotting-oranges/
思路:
很典型的BFS,就是不断生成新的状态结点,然后找到直接return(最短/最小)
但是注意了,这个题目可能不只一个烂橘子,也就是可能是由多个点进行bfs
=> 单源广度优先搜索
=> 多源广度优先搜索

package 每日一题;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

/*

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

 值 0 代表空单元格;
 值 1 代表新鲜橘子;
 值 2 代表腐烂的橘子。

 每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。

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


 示例 1:
 输入:[[2,1,1],[1,1,0],[0,1,1]]
 输出:4

 示例 2:
 输入:[[2,1,1],[0,1,1],[1,0,1]]
 输出:-1
 解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。

 示例 3:
 输入:[[0,2]]
 输出:0
 解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。

 提示:

 1. 1 <= grid.length <= 10
 2. 1 <= grid[0].length <= 10
 3. grid[i][j] 仅为 0、1 或 2


 来源:力扣(LeetCode)
 链接:https://leetcode-cn.com/problems/rotting-oranges
 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 */

public class code01_腐烂的橘子 {
    int R;
    int C;
    boolean[][] vis;

    int[] dr = new int[] { -1, 0, 1, 0 };
    int[] dc = new int[] { 0, -1, 0, 1 };

    public void print(int[][] grid) {
        for (int[] arr : grid) {
            System.out.println(Arrays.toString(arr));
        }
        System.out.println("===================");
    }

    public boolean in(int r, int c) {
        return 0 <= r && r < R && 0 <= c && c < C;
    }

    public boolean checkOK(int[][] grid) {
        for (int i = 0; i < R; i += 1) {
            for (int j = 0; j < C; j += 1) {
                if (grid[i][j] == 1) {
                    return false;
                }
            }
        }
        return true;
    }

    // 检查是否有新鲜橘子
    public boolean checkGood(int[][] grid) {
        for (int r = 0; r < R; r += 1) {
            for (int c = 0; c < C; c += 1) {
                if (grid[r][c] == 1) {
                    return true;
                }
            }
        }
        return false;
    }

    public int orangesRotting(int[][] grid) {
        R = grid.length;
        C = grid[0].length;
        // 最大就是 10 * 10
        vis = new boolean[10][10];

        Queue<Node> q = new LinkedList<Node>();
        // depth: 存放对应深度和步数的
        // key: 当前层数 value: 最少的步数
        Map<Integer, Integer> depth = new HashMap<Integer, Integer>();

        if (!checkGood(grid)) { // 如果没有新鲜橘子的话,直接return 0
            return 0;
        }

        for (int r = 0; r < R; r += 1) {
            for (int c = 0; c < C; c += 1) {
                if (grid[r][c] == 2) {
                    // 把坏橘子都加入,作为第0层
                    // 其实多源BFS只是把第0层加为多个
                    vis[r][c] = true;
                    // 把二维数组的下标转换为一个唯一值
                    int code = r * C + c;
                    depth.put(code, 0);
                    q.offer(new Node(0, r, c));
                }
            }
        }
        int ans = 0;
        while (!q.isEmpty()) {

            // 这是多源不一样的地方,之前都是取一个,现在是取一层
            int len = q.size();
            for (int i = 0; i < len; i += 1) { // 按层次来
                Node now = q.poll();
                for (int j = 0; j < 4; j += 1) {
                    int tr = now.r + dr[j];
                    int tc = now.c + dc[j];
                    // 判断是否越界和判断是否访问过
                    // 而且被污染的一定要是新鲜的橘子
                    if (in(tr, tc) && !vis[tr][tc] && grid[tr][tc] == 1) {
                        vis[tr][tc] = true;
                        grid[tr][tc] = 2;
                        depth.put(tr * C + tc, depth.get(now.r * C + now.c)+1);
                        ans = depth.get(tr * C + tc);
                        q.offer(new Node(now.steps + 1, tr, tc));
                    }
                }
            }
            // print(grid);
            
        }
        if(checkGood(grid)){ // 如果还有
            return -1;
        }

        return ans;
    }

    class Node {
        int steps; // 记录步数
        int r, c; // 只需要记录需要修改的点,不用怎么地图都记录

        public Node(int steps, int r, int c) {
            super();
            this.steps = steps;
            this.r = r;
            this.c = c;
        }

    }

    public static void main(String[] args) {
        // 测试代码
         int[][] grid = { { 2, 1, 1 }, { 1, 1, 0 }, { 0, 1, 1 } };
//      int[][] grid = { { 0, 2 } };
        code01_腐烂的橘子 xx = new code01_腐烂的橘子();
        System.out.println(xx.orangesRotting(grid));
    }

}

猜你喜欢

转载自www.cnblogs.com/Rowry/p/12417588.html