• LeetCode——542. 01 矩阵


    给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。

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

    示例 1:
    输入:

    0 0 0
    0 1 0
    0 0 0
    

    输出:

    0 0 0
    0 1 0
    0 0 0
    

    示例 2:
    输入:

    0 0 0
    0 1 0
    1 1 1
    

    输出:

    0 0 0
    0 1 0
    1 2 1
    

    注意:

    1. 给定矩阵的元素个数不超过 10000。
    2. 给定矩阵中至少有一个元素是 0。
    3. 矩阵中的元素只在四个方向上相邻: 上、下、左、右。

    BFS

    我们可以首先遍历一次矩阵,将值为0的点都存入queue,将值为1的点改为INT_MAX。

    然后开始BFS遍历,从queue中取出一个数字,遍历其周围四个点,如果越界或者周围点的值小于等于当前值加1,则直接跳过。

    因为周围点的距离更小的话,就没有更新的必要,否则将周围点的值更新为当前值加1,然后把周围点的坐标加入queue,参见代码如下:

    c++

    class Solution {
    public:
        vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
            int m = matrix.size(), n = matrix[0].size();
            vector<vector<int>> dirs{{0,-1},{-1,0},{0,1},{1,0}};
            queue<pair<int, int>> q;
            for (int i = 0; i < m; ++i) {
                for (int j = 0; j < n; ++j) {
                    if (matrix[i][j] == 0) q.push({i, j});
                    else matrix[i][j] = INT_MAX;
                }
            }
            while (!q.empty()) {
                auto t = q.front(); q.pop();
                for (auto dir : dirs) {
                    int x = t.first + dir[0], y = t.second + dir[1];
                    if (x < 0 || x >= m || y < 0 || y >= n || matrix[x][y] <= matrix[t.first][t.second] + 1) continue;
                    matrix[x][y] = matrix[t.first][t.second] + 1;
                    q.push({x, y});
                }
            }
            return matrix;
        }
    };
    

    动态规划

    首先建立一个和matrix大小相等的矩阵res,初始化为很大的值,这里我们用INT_MAX-1。

    然后我们遍历matrix矩阵,当遇到为0的位置,我们将结果res矩阵的对应位置也设为0。

    然后就是这个解法的精髓了,如果不是0的地方,我们在第一次扫描的时候,比较其左边和上边的位置,取其中较小的值,再加上1,来更新结果res中的对应位置。

    如果初始化为INT_MAX就会整型溢出,不过放心,由于是取较小值,res[i][j]永远不会取到INT_MAX,所以不会有再加1溢出的风险。

    第一次遍历我们比较了左和上的方向,那么我们第二次遍历就要比较右和下的方向,注意两种情况下我们不需要比较,一种是当值为0时,还有一种是当值为1时,这两种情况下值都不可能再变小了,所以没有更新的必要,参见代码如下:

    c++

    class Solution {
    public:
        vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
            int m = matrix.size(), n = matrix[0].size();
            vector<vector<int>> res(m, vector<int>(n, INT_MAX - 1));
            for (int i = 0; i < m; ++i) {
                for (int j = 0; j < n; ++j) {
                    if (matrix[i][j] == 0) res[i][j] = 0;
                    else {
                        if (i > 0) res[i][j] = min(res[i][j], res[i - 1][j] + 1);
                        if (j > 0) res[i][j] = min(res[i][j], res[i][j - 1] + 1);
                    }
                }
            }
            for (int i = m - 1; i >= 0; --i) {
                for (int j = n - 1; j >= 0; --j) {
                    if (res[i][j] != 0 && res[i][j] != 1) {
                        if (i < m - 1) res[i][j] = min(res[i][j], res[i + 1][j] + 1);
                        if (j < n - 1) res[i][j] = min(res[i][j], res[i][j + 1] + 1);
                    }
                }
            }
            return res;
        }
    };
    

    python

    class Solution:
        def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
            for i in range(len(matrix)):
                for j in range(len(matrix[0])):
                    l,t= 10001,10001
                    if matrix[i][j] != 0:
                        if i > 0:
                            t = matrix[i - 1][j]
                        
                        if j > 0:
                            l = matrix[i][j - 1]
                        
                        matrix[i][j] = min(l,t) + 1
            
            for i in range(len(matrix) - 1, -1 ,-1):
                for j in range(len(matrix[0]) - 1, -1, -1):
                    r,b = 10001,10001
                    if matrix[i][j] != 0:
                        if i < len(matrix) - 1:
                            b = matrix[i + 1][j]
    
                        if j < len(matrix[0]) - 1:
                            r = matrix[i][j + 1]
    
                        matrix[i][j] = min(matrix[i][j], min(r,b) + 1)
            return matrix
    
  • 相关阅读:
    BZOJ 3754 Tree之最小方差树
    【CSS】318- CSS实现宽高等比自适应容器
    【Vuejs】317- 提升90%加载速度——Vuecli下的首屏性能优化
    【H5】316- 移动端H5跳坑指南
    【每周小回顾】2- 一起回顾上周精彩内容
    【Webpack】315- 手把手教你搭建基于 webpack4 的 vue2 多页应用
    【Web技术】314- 前端组件设计原则
    【JS】313- 复习 回流和重绘
    【JS】312- 复习 JavaScript 严格模式(Strict Mode)
    【Canvas】311- 解决 canvas 在高清屏中绘制模糊的问题
  • 原文地址:https://www.cnblogs.com/wwj99/p/12275886.html
Copyright © 2020-2023  润新知