力扣542. 01 矩阵 BFS详解,C++语言实现

题目如下:

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

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

输入:

0 0 0
0 1 0
0 0 0

输出:

0 0 0
0 1 0
0 0 0

输入:

0 0 0
0 1 0
1 1 1

输出:

0 0 0
0 1 0
1 2 1

解析如下:

从每一个0位置向上下左右四个方向进行广播,同时将点距离0的长度更新为最短。
在这里插入图片描述
边做边解释,以题目中给出的实例2为例:
首先创造一个result 数组,也就是最终返回的记录每个元素到最近的0的距离的数组。

~ ~ ~
~ ~ ~
~ ~ ~

将result数组初始为无穷大,表示距离0的距离为无穷大。
便利原数组,将原数组为0的项,在result中变为0(即,距离0的距离为0),并将所有0的位置入队。

0 0 0
0 ~ 0
~ ~ ~
//当前que的状态:00) (01) (02) (10) (12

进行BFS,从每一个0位置向上下左右四个方向进行广播,如果广播到的位置距离0的距离,大于,当前位置距离0的距离加一,则将广播到的位置距离0的位置更新为当前位置距离0的距离加一,将当前位置出队。

//当前位置(0,0):向上下左右扩展
//扩展完毕结果:
0 0 0
0 ~ 0
~ ~ ~
//当前que的状态:
(0,1) (0,2) (1,0) (1,2)
//当前位置(0,1):向上下左右扩展

扩展到位置(1,1)时,位置(0,1)距离0的距离为0,
而位置(1,1)距离0的位置为无穷~,将~更新为0+1.
并将(1,1)入队,以进行下一次从(1,1)开始的广播。

//扩展完毕结果:
0 0 0
0 1 0
~ ~ ~
//当前que的状态:
(0,2) (1,0) (1,2)(1,1)
//当前位置(0,2):向上下左右扩展
//扩展完毕结果:
0 0 0
0 1 0
~ ~ ~
//当前que的状态:
(1,0) (1,2)(1,1)
//当前位置(1,0):向上下左右扩展

扩展到位置(1,0)时,位置(1,0)距离0的距离为0,
而位置(2,0)距离0的位置为无穷~,将~更新为0+1.
并将(2,0)入队,以进行下一次从(2,0)开始的广播。

//扩展完毕结果:
0 0 0
0 1 0
1 ~ ~
//当前que的状态:
(1,2)(1,1)(2,0)
//当前位置(1,2):向上下左右扩展

扩展到位置(1,2)时,位置(1,2)距离0的距离为0,
而位置(2,2)距离0的位置为无穷~,将~更新为0+1.
并将(2,2)入队,以进行下一次从(2,2)开始的广播。

//扩展完毕结果:
0 0 0
0 1 0
1 ~ 1
//当前que的状态:
(1,1)(2,0) (2,2)
//当前位置(1,1):向上下左右扩展

扩展到位置(1,1)时,位置(1,1)距离0的距离为1,
而位置(2,1)距离0的位置为无穷~,将~更新为1+1.
并将(2,1)入队,以进行下一次从(2,1)开始的广播。

//扩展完毕结果:
0 0 0
0 1 0
1 2 1
//当前que的状态:
(2,0) (2,2) (2,1)

。。。。。。

//扩展完毕结果:
0 0 0
0 1 0
1 2 1

广播过程如上述过程所示
其实本质还是对所有的0向外广播,将距离0最小的距离记录下来,
首先是与0的距离为1的向外扩展,即对(0,0) (0,1) (0,2) (1,0) (1,2)向外扩展,
在这里插入图片描述
如果有成功扩展,则将该点入队,方便从该点开始进行距离0的距离为2的扩展,
在这里插入图片描述
。。。。
反复,如果能成功扩展,则更新距离,入队,进行下一次扩展。

代码如下:

class Solution {
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
        int numr = matrix.size();
        int numc = matrix[0].size();
        vector<pair<int,int>> around = {{0,1},{0,-1},{-1,0},{1,0}};
        vector<vector<int>> result(numr, vector<int>(numc, INT_MAX));
        queue<pair<int,int>> que;
        for(int i = 0; i < numr; i++){
            for(int j = 0; j < numc; j++){
                if(matrix[i][j] == 0){
                    result[i][j] = 0;
                    que.push({i, j});
                }
            }
        }
        while(!que.empty()){
            auto temp = que.front();
            que.pop();
            for(int i = 0; i < 4; i++){
                int x = temp.first + around[i].first;
                int y = temp.second + around[i].second;
                if(x >= 0 && x < numr && y >= 0 && y < numc){
                    if(result[x][y] > result[temp.first][temp.second] + 1){
                        result[x][y] = result[temp.first][temp.second] + 1;
                        que.push({x, y});
                    }
                }
            }
        }
        return result;
    }
};
发布了6 篇原创文章 · 获赞 0 · 访问量 164
App 阅读领勋章
微信扫码 下载APP
阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览