LeetCode-542. 01 矩阵

1、题目描述

给定一个由 01 组成的矩阵 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、代码

cpp 复制代码
#include <queue>    
#include <utility>  
#include <vector>   
using namespace std;

class Solution
{
  public:
    // 计算矩阵中每个元素到最近0的距离
    vector<vector<int>> updateMatrix(vector<vector<int>>& mat)
    {
        int row = mat.size();     
        int col = mat[0].size();  

        vector<vector<int>> ret(row, vector<int>(col, -1));
        
        // BFS队列,用于存储待处理的坐标(宽搜的核心数据结构)
        queue<pair<int, int>> q;

        // 第一步:初始化所有0的位置
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                if (mat[i][j] == 0) {
                    ret[i][j] = 0;   // 0到自身的距离为0
                    q.push({i, j});  // 将所有0的坐标加入队列,作为BFS的起点
                }
            }
        }

        // 定义四个方向的偏移量:上、下、左、右(用于遍历相邻单元格)
        vector<pair<int, int>> dirs = {{-1, 0},
                                       {1, 0},  
                                       {0, -1},
                                       {0, 1}};  

        // 第二步:多源BFS扩散计算距离
        while (!q.empty()) {
            // 取出队列头部的坐标(当前处理的单元格)
            auto [i, j] = q.front();

            // 遍历四个相邻方向
            for (auto [x, y] : dirs) {
                // 计算相邻单元格的坐标
                int dx = i + x;  // 新行坐标 = 当前行 + 方向偏移
                int dy = j + y;  // 新列坐标 = 当前列 + 方向偏移

                // 检查相邻单元格是否有效:
                // 1. 不超出矩阵边界(行和列都在有效范围内)
                // 2. 该位置尚未计算距离(ret[dx][dy] == -1)
                if ((dx >= 0 && dx < row) && (dy >= 0 && dy < col) &&
                    (ret[dx][dy] == -1)) {
                    // 相邻单元格的距离 = 当前单元格距离 + 1(因为相邻)
                    ret[dx][dy] = ret[i][j] + 1;
                    // 将新计算的单元格加入队列,用于后续扩散
                    q.push({dx, dy});
                }
            }
            // 处理完当前单元格后出队
            q.pop();
        }

        // 返回计算好的距离矩阵
        return ret;
    }
};

3、解题思路

  1. 初始化部分:通过双重循环找到所有 0 的位置,将其距离设为 0 并加入队列,作为 BFS 的多源起点。
  2. 方向数组:定义了上下左右四个方向的偏移量,避免了重复编写判断相邻单元格的代码。
  3. BFS 核心逻辑
    • 从队列中取出当前单元格,遍历其四个相邻位置
    • 对每个有效且未计算距离的相邻单元格,更新其距离(当前距离 + 1)并加入队列
    • 保证每个单元格只被计算一次,且首次计算的距离就是到最近 0 的最短距离
  4. 为什么有效:同时将所有 0 作为起点(距离为 0) 从 0 开始向外扩散,每个 1 被首次访问时,一定是被最近的 0所扩散到的,因此首次计算的距离就是最短距离
相关推荐
日拱一卒——功不唐捐几秒前
字符串匹配:暴力法和KMP算法(C语言)
c语言·算法
renke336410 分钟前
Flutter for OpenHarmony:数字涟漪 - 基于扩散算法的逻辑解谜游戏设计与实现
算法·flutter·游戏
AI科技星14 分钟前
从ZUFT光速螺旋运动求导推出自然常数e
服务器·人工智能·线性代数·算法·矩阵
老鼠只爱大米18 分钟前
LeetCode经典算法面试题 #78:子集(回溯法、迭代法、动态规划等多种实现方案详细解析)
算法·leetcode·动态规划·回溯·位运算·子集
执着25922 分钟前
力扣hot100 - 199、二叉树的右视图
数据结构·算法·leetcode
I_LPL25 分钟前
day21 代码随想录算法训练营 二叉树专题8
算法·二叉树·递归
可编程芯片开发32 分钟前
基于PSO粒子群优化PI控制器的无刷直流电机最优控制系统simulink建模与仿真
人工智能·算法·simulink·pso·pi控制器·pso-pi
cpp_250133 分钟前
P8448 [LSOT-1] 暴龙的土豆
数据结构·c++·算法·题解·洛谷
YGGP34 分钟前
【Golang】LeetCode 49. 字母异位词分组
leetcode
lcj251134 分钟前
深入理解指针(4):qsort 函数 & 通过冒泡排序实现
c语言·数据结构·算法