01 矩阵

204 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

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 <= 104
1 <= m * n <= 104
mat[i][j] is either 0 or 1.
mat 中至少有一个 0 

2、思路分析

题目要求我们计算矩阵中每一个数字距离0的最近距离,只是一种很常见的问题,我们可以从以下几个方法考虑入手:

(1)暴力搜索

我们可以遍历这个矩阵,遇到1的时候就从该位置进行发散式搜索,找到距离最近的0,这是最直接的做法,但是其复杂度太高了,我们可以pass掉这个做法。

(2)深度优先搜索

我们可以从左上角开始进行深搜,遇到0就将当前所需最小步数置为0,否则则累加1并更新当前位置的最小步骤数值,遍历完后即可获得答案。深搜是一种有效的做法,但我们需要注意剪枝操作,否则其复杂度还是很高。

(3)广度优先搜索

这次我使用的是广度优先搜索,我们需要的是计算与0的距离,所以我们可以反过来思考,计算从0的位置出发,到每一个位置所需的步数,如下图所示:

1648556693(1).jpg

主要步骤如下:

  • 初始化步数矩阵,并将矩阵中为0的坐标入队
for(let i = 0; i < res.length; i++){
    res[i] = new Array(mat[0].length).fill(Infinity);
    for(let j = 0; j < mat[i].length; j++){
        if(mat[i][j] === 0){
            queue.push([i,j]);
            res[i][j] = 0;
        }
    }
}
  • 元素出队并将其四周的位置步数更新
while(queue.length > 0){
    let q = queue.shift();
    const dx = [1,0,-1,0],dy = [0,1,0,-1];
    const x = q[0],y = q[1],val = res[x][y] + 1;
    for(let i = 0; i < 4; i++){
        const nx = dx[i] + x,ny = y + dy[i];
        if(nx >= mat.length || nx < 0 || ny > mat[0].length || ny < 0) continue;
        if(val < res[nx][ny]){
            res[nx][ny] = val;
            queue.push([nx,ny]);
        }
    }
}
  • 将四周需要更新的位置入队
if(val < res[nx][ny]){
    res[nx][ny] = val;
    queue.push([nx,ny]);
}

AC代码

/**
 * @param {number[][]} mat
 * @return {number[][]}
 */
var updateMatrix = function(mat) {
    let res = new Array(mat.length);
    let queue = [];
    for(let i = 0; i < res.length; i++){
        res[i] = new Array(mat[0].length).fill(Infinity);
        for(let j = 0; j < mat[i].length; j++){
            if(mat[i][j] === 0){
                queue.push([i,j]);
                res[i][j] = 0;
            }
        }
    }
    while(queue.length > 0){
        let q = queue.shift();
        const dx = [1,0,-1,0],dy = [0,1,0,-1];
        const x = q[0],y = q[1],val = res[x][y] + 1;
        for(let i = 0; i < 4; i++){
            const nx = dx[i] + x,ny = y + dy[i];
            if(nx >= mat.length || nx < 0 || ny > mat[0].length || ny < 0) continue;
            if(val < res[nx][ny]){
                res[nx][ny] = val;
                queue.push([nx,ny]);
            }
        }
    }
    return res;
};