美文网首页
542. 01 矩阵、1162. 地图分析、994. 腐烂的橘子

542. 01 矩阵、1162. 地图分析、994. 腐烂的橘子

作者: Abeants | 来源:发表于2021-11-07 21:06 被阅读0次

本次的三道题都用了多源点BFS的方法,关于什么是多源点BFS呢,就是求很多个起点到一个终点的关系,就将终点入队,反过来求。如下面三道题:

542. 01 矩阵

给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。

两个相邻元素间的距离为 1 。

示例 1:


输入:mat = [[0,0,0],[0,1,0],[0,0,0]]
输出:[[0,0,0],[0,1,0],[0,0,0]]

示例 2:


输入:mat = [[0,0,0],[0,1,0],[1,1,1]]
输出:[[0,0,0],[0,1,0],[1,2,1]]

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

解题思路及方法

这道题要求的是每一个1离最近0的距离,那么可以假设这个矩阵就只有一个0,其余的都是1,就是多源点BFS问题,所以就将所有的0入队,然后开始用BFS来计算。

用一个新的dist矩阵来记录每一个1距离最近的0的距离。

class Solution {
    // 方向
    static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    public int[][] updateMatrix(int[][] mat) {
        int m = mat.length,n = mat[0].length;
        // 记录已访问的节点
        boolean[][] visited = new boolean[m][n];
        // 初始队列
        Queue<int[]> queue = new LinkedList<>();
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat[0].length; j++) {
                // 所有0全部入队
                if (mat[i][j] == 0) {
                    queue.offer(new int[]{i, j});
                    visited[i][j] = true;
                }
            }
        }

        // 记录距离
        int[][] dist = new int[m][n];
        // 搜索0位置的四周,并记录距离
        while (!queue.isEmpty()) {
            int[] cur = queue.poll();
            int row = cur[0], cln = cur[1];
            for (int i = 0; i < 4; i++) {
                int ni = row + dirs[i][0];
                int nj = cln + dirs[i][1];
                if (ni >= 0 && nj >= 0 && ni < m &&  nj < n && !visited[ni][nj]) {
                    dist[ni][nj] = dist[row][cln] + 1;
                    queue.offer(new int[]{ni, nj});
                    visited[ni][nj] = true;
                }
            }
        }

        return dist;
    }
}

结果如下:

1162. 地图分析

你现在手里有一份大小为 N x N 的 网格 grid,上面的每个 单元格 都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地,请你找出一个海洋单元格,这个海洋单元格到离它最近的陆地单元格的距离是最大的。

我们这里说的距离是「曼哈顿距离」( Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个单元格之间的距离是 |x0 - x1| + |y0 - y1| 。

如果网格上只有陆地或者海洋,请返回 -1。

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

解题思路及方法

这道题跟上面是同样的方法,只不过是找到0距离最近的1的距离,所以就将所有的1入队,然后进行BFS算法。

注意需要判断全1或者全0的情况,就只用判断队列的长度是否为m*n或者0。

class Solution {
    // 方向
    static int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    public int maxDistance(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        // 初始队列
        Queue<int[]> queue = new LinkedList<>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    queue.offer(new int[]{i, j});
                } else {
                    grid[i][j] = -1;
                }
            }
        }
        // 如果全为陆地或嗨哟
        if (queue.size() == m * n || queue.size() == 0) return -1;
        // BFS
        while (!queue.isEmpty()) {
            int[] cur = queue.poll();
            int row = cur[0], cln = cur[1];
            for (int i = 0; i < 4; i++) {
                int newRow = row + dirs[i][0];
                int newCln = cln + dirs[i][1];
                if (newRow < 0 || newCln < 0 || newRow >= m || newCln >= n || grid[newRow][newCln] > 0) continue;
                grid[newRow][newCln] = grid[row][cln] + 1;
                // 周围节点入队
                queue.offer(new int[]{newRow, newCln});
            }
        }

        int maxDist = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                maxDist = Math.max(maxDist, grid[i][j]);
            }
        }

        return maxDist - 1;
    }
}

结果如下:

994. 腐烂的橘子

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

值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。

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

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

解题思路及方法

一样的思想,腐烂的橘子先入队,然后影响周围的橘子。

需要判断的是没有橘子,即全0的情况,就用一个参数计数。

class Solution {
    public static int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    public int orangesRotting(int[][] grid) {
        int m = grid.length, n = grid[0].length;

        int countZero = 0;
        // 初始队列
        Queue<int[]> queue = new LinkedList<>();
        // 所有腐烂橘子入队
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 2) {
                    queue.offer(new int[]{i, j});
                }
                // 考虑0的情况
                if (grid[i][j] == 0) {
                    countZero++;
                }
            }
        }
        // 如果没有橘子
        if (countZero == m * n) return 0;

        int time = 0;
        // BFS将所有腐烂橘子四周的橘子腐烂
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int[] cur = queue.poll();
                int row = cur[0], cln = cur[1];
                // 四周橘子腐烂
                for (int j = 0; j < 4; j++) {
                    int newRow = row + dirs[j][0];
                    int newCln = cln + dirs[j][1];
                    // 出界或者周围不是新鲜橘子,continue
                    if (newRow < 0 || newCln < 0 || newRow >= m || newCln >= n || grid[newRow][newCln] != 1) continue;
                    grid[newRow][newCln] = 2;
                    queue.offer(new int[]{newRow, newCln});
                }
            }
            // 更新时间
            time++;
        }

        // 判断是否还有新鲜橘子
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) return -1;
            }
        }
        
        return time - 1;
    }
}

结果如下:

相关文章

  • 542. 01 矩阵、1162. 地图分析、994. 腐烂的橘子

    本次的三道题都用了多源点BFS的方法,关于什么是多源点BFS呢,就是求很多个起点到一个终点的关系,就将终点入队,反...

  • 994.腐烂的橘子

    原题 https://leetcode-cn.com/problems/rotting-oranges/ 解题思路...

  • 994.腐烂的橘子

    由题目我们可以知道每分钟每个腐烂的橘子都会使上下左右相邻的新鲜橘子腐烂,这其实是一个模拟广度优先搜索的过程。所谓广...

  • queue:994.腐烂的橘子

    考点:队列 动态的遍历queue 遍历queue的同时会追加元素 广度优先搜索算法

  • LeetCode 994. 腐烂的橘子

    在给定的网格中,每个单元格可以有以下三个值之一: 值 0 代表空单元格; 值 1 代表新鲜橘子; 值 2 代表腐烂...

  • Leetcode 994. 腐烂的橘子

    题目描述 在给定的网格中,每个单元格可以有以下三个值之一: 值 0 代表空单元格; 值 1 代表新鲜橘子; 值 2...

  • 994. 腐烂的橘子(Python)

    难度:★★★☆☆类型:数组方法:宽度优先搜索,队列 题目 力扣链接请移步本题传送门[https://leetcod...

  • LeetCode 542. 01 矩阵

    542. 01 矩阵 题目来源:https://leetcode-cn.com/problems/01-matri...

  • 『图;广度优先遍历』地图分析1162

    题目相关 原题链接:1162. 地图分析 - 力扣(LeetCode) 涉及知识:图、广度优先遍历 题目难度:★★...

  • BFS / DFS 典型例题

    图的BFS: leetcode:1162 地图分析leetcode:542 01矩阵 树的BFS: 图的DFS: ...

网友评论

      本文标题:542. 01 矩阵、1162. 地图分析、994. 腐烂的橘子

      本文链接:https://www.haomeiwen.com/subject/xwuezltx.html