栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

剑指 Offer II 107. 矩阵中的距离

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

剑指 Offer II 107. 矩阵中的距离

剑指 Offer II 107. 矩阵中的距离

文章目录
  • 剑指 Offer II 107. 矩阵中的距离
  • 一、题目
    • 1.题目描述
    • 2.基础框架
    • 3.解题思路
    • 4.总结

一、题目

原题链接:Offer II 107. 矩阵中的距离

1.题目描述

给定一个由 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]]

提示:

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n <= 10^4
  • 1 <= m * n <= 10^4
  • mat[i][j] is either 0 or 1.
  • mat 中至少有一个 0

注意:本题与leetcode 542 题相同:01矩阵

2.基础框架

C++基础框架代码如下:

vector > updateMatrix(vector >& mat){
}
3.解题思路
  • 题目分析
  1. 题目目标是返回矩阵,其中每个单元格子中的值为到最近0的距离。
  2. 可以从矩阵中0对应的位置出发,分别对它们进行广度优先遍历周围的位置,从而周围位置得到距离0位置的值。
  3. 为了得到矩阵中所有0的位置,需要遍历一次矩阵mat,并将0的位置以pair类型存入队列q中。
  4. 开始时队列中都是0,分别从0出发,对它们的周围的位置进行扩张,所谓扩张就是向这些位置赋值离大本营0的距离。每次扩张只会访问上下左右的位置。不同阵营的0所遍历过的位置一定是距离所属大本营的那个0最近的,因为这些大本营的每次遍历的层级都是一样的。所以当遇到由不同阵营访问过的位置,不需要再访问。
  5. 因为周围的位置可能是可能也是一个大本营0,所以进行距离赋值的时候还需要对这些位置进行判断,如果为0,那该位置仍为0,如果不为0,那接着判断是否为其他阵营访问过的位置,如果是,则不会访问该位置,如果不是,那就给这个位置进行距离赋值。

为了方便理解,用图围绕上述捋一遍:

  1. 队列中假如有两个0的阵营,每个阵营轮流进行领地扩张,黄色领地先行,绿色领地紧接其后。

2. 这一轮黄色领地继续扩张,绿色领地在黄色领地扩张后,也紧接着进行扩张。

3.最后两个领地都扩张结束了,得到的领地地图,就是我们要返回的矩阵啦。

  • 实现代码:

    #include 
    #include 
    #include 
    using namespace std;
    class Solution {
    public:
        void bfs(vector >&res, queue >& q, int m, int n) 
        {
            vector > dirs{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
            while (!q.empty())
            {
                auto pos = q.front();
                q.pop();
                int dist = res[pos.first][pos.second];
                for (auto& d : dirs)
                {
                    int r = pos.first + d[0];
                    int c = pos.second + d[1];
                    if (r >= 0 && r < m && c >= 0 && c < n)
                    {
                        if (dist + 1 < res[r][c])	//判断res[r][c]是否为0 或 是否为其他0阵营访问过的位置,如果是自己阵营或其他阵营遍历过的位置则不再访问。
                        {
                            res[r][c] = dist + 1;
                            q.push({r, c});
                        }
                    }
                }
            }
            return ;
        }
        vector> updateMatrix(vector>& mat) {
            queue >q;
            int i, j;
            int m = mat.size(), n = mat[0].size();
            vector > res(m, vector(n, INT_MAX));
            for (i = 0; i < m; ++i)
            {
                for (j = 0; j < n; ++j)
                {
                    if (mat[i][j] == 0)
                    {
                        q.push({i, j});
                        res[i][j] = 0;
                    }
                }
            }
            bfs(res, q, m, n);
            return res;
        }
    };
    
4.总结

​ 知识点:广度优先遍历

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/832834.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号