当前位置: 首页 > news >正文

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


comments: true
edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20107.%20%E7%9F%A9%E9%98%B5%E4%B8%AD%E7%9A%84%E8%B7%9D%E7%A6%BB/README.md

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

题目描述

给定一个由 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 中至少有一个

 

注意:本题与主站 542 题相同:https://leetcode.cn/problems/01-matrix/

解法

方法一:多源 BFS

初始化结果矩阵 ans,所有 0 的距离为 0,所以 1 的距离为 -1。初始化队列 q 存储 BFS 需要检查的位置,并将所有 0 的位置入队。

循环弹出队列 q 的元素 p(i, j),检查邻居四个点。对于邻居 (x, y),如果 ans[x][y] = -1,则更新 ans[x][y] = ans[i][j] + 1。同时将 (x, y) 入队。

Python3
class Solution:
    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:
        m,n=len(mat),len(mat[0])
        res=[[-1]*n for _ in range(m)]
        dir = (1, 0, -1, 0, 1)

        # 第一层
        q=deque()
        for i,row in enumerate(mat):
            for j,v in enumerate(row):
                if v==0:
                    q.append((i,j)) #所有的0都相当于第一层(起始位置)
                    res[i][j] = 0
        # BFS扩展
        while q:
        	# for _ in range(len(q)): # 使用内层for循环可以确保逐层处理,保持层级结构,而不使用的话则会按入队顺序处理,忽略层级
	            i,j=q.popleft()
	
	            for dx,dy in pairwise(dir):
	                nx,ny=i+dx,j+dy
	                if 0<=nx<m and 0<=ny<n and res[nx][ny]==-1: #【关键判断】:res[nx][ny]==-1,即相当于used,又防止bfs无限递归(重复错误覆盖res)
	                    res[nx][ny]=res[i][j]+1
	                    q.append((nx,ny))

        return res
Java
class Solution {

    public int[][] updateMatrix(int[][] mat) {
        int m = mat.length, n = mat[0].length;
        int[][] ans = new int[m][n];
        for (int i = 0; i < m; ++i) {
            Arrays.fill(ans[i], -1);
        }
        Deque<int[]> q = new LinkedList<>();
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (mat[i][j] == 0) {
                    ans[i][j] = 0;
                    q.offer(new int[] {i, j});
                }
            }
        }
        int[] dirs = new int[] {-1, 0, 1, 0, -1};
        while (!q.isEmpty()) {
            int[] t = q.poll();
            for (int i = 0; i < 4; ++i) {
                int x = t[0] + dirs[i];
                int y = t[1] + dirs[i + 1];
                if (x >= 0 && x < m && y >= 0 && y < n && ans[x][y] == -1) {
                    ans[x][y] = ans[t[0]][t[1]] + 1;
                    q.offer(new int[] {x, y});
                }
            }
        }
        return ans;
    }
}
C++
class Solution {
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
        int m = mat.size(), n = mat[0].size();
        vector<vector<int>> ans(m, vector<int>(n, -1));
        queue<pair<int, int>> q;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (mat[i][j] == 0) {
                    ans[i][j] = 0;
                    q.emplace(i, j);
                }
            }
        }
        vector<int> dirs = {-1, 0, 1, 0, -1};
        while (!q.empty()) {
            auto p = q.front();
            q.pop();
            for (int i = 0; i < 4; ++i) {
                int x = p.first + dirs[i];
                int y = p.second + dirs[i + 1];
                if (x >= 0 && x < m && y >= 0 && y < n && ans[x][y] == -1) {
                    ans[x][y] = ans[p.first][p.second] + 1;
                    q.emplace(x, y);
                }
            }
        }
        return ans;
    }
};
Go
func updateMatrix(mat [][]int) [][]int {
	m, n := len(mat), len(mat[0])
	ans := make([][]int, m)
	for i := range ans {
		ans[i] = make([]int, n)
		for j := range ans[i] {
			ans[i][j] = -1
		}
	}
	type pair struct{ x, y int }
	var q []pair
	for i, row := range mat {
		for j, v := range row {
			if v == 0 {
				ans[i][j] = 0
				q = append(q, pair{i, j})
			}
		}
	}
	dirs := []int{-1, 0, 1, 0, -1}
	for len(q) > 0 {
		p := q[0]
		q = q[1:]
		for i := 0; i < 4; i++ {
			x, y := p.x+dirs[i], p.y+dirs[i+1]
			if x >= 0 && x < m && y >= 0 && y < n && ans[x][y] == -1 {
				ans[x][y] = ans[p.x][p.y] + 1
				q = append(q, pair{x, y})
			}
		}
	}
	return ans
}
Swift
class Solution {
    func updateMatrix(_ mat: [[Int]]) -> [[Int]] {
        let m = mat.count
        let n = mat[0].count
        var ans = Array(repeating: Array(repeating: -1, count: n), count: m)
        var queue = [(Int, Int)]()

        for i in 0..<m {
            for j in 0..<n {
                if mat[i][j] == 0 {
                    ans[i][j] = 0
                    queue.append((i, j))
                }
            }
        }

        let dirs = [-1, 0, 1, 0, -1]

        while !queue.isEmpty {
            let (i, j) = queue.removeFirst()
            for d in 0..<4 {
                let x = i + dirs[d]
                let y = j + dirs[d + 1]
                if x >= 0 && x < m && y >= 0 && y < n && ans[x][y] == -1 {
                    ans[x][y] = ans[i][j] + 1
                    queue.append((x, y))
                }
            }
        }

        return ans
    }
}

相关文章:

  • 专线、云 和 物联网(IoT)
  • 【css酷炫效果】纯CSS实现进度条加载动画
  • LightRAG简要概述
  • cmake --build . --config Release和make是1个意思吗
  • SQLMesh系列教程:利用date_spine宏构建日期序列实践指南
  • 网络工程安全从入门到“入魂“教学案
  • CellOracle|基因扰动研究基因功能|基因调控网络+虚拟干预
  • 使用STM32CubeMX+DMA+空闲中断实现串口接收和发送数据(STM32G070CBT6)
  • 黑客攻击deepseek服务原理解析
  • 基于SpringBoot的“酒店管理系统”的设计与实现(源码+数据库+文档+PPT)
  • 东方通TongHttpServer:企业级服务代理中间件的卓越之选
  • 《自然》:陆地蒸散量研究的统计失误被撤回-空间加权平均的计算方法
  • Unity特效动态合批问题
  • LINUX驱动学习之IIC驱动-----以AP3216C为例
  • 【css酷炫效果】纯CSS实现按钮流光边框
  • [QT]深入理解Qt中的信号与槽机制
  • 什么是梯度方差和缩放因子
  • PrimeTime:timing_report_unconstrained_paths变量
  • java的WeakHashMap可以用来做缓存使用?强软弱虚四种引用对比
  • 前端 - js - - 防抖和节流
  • 做网站前台用什么问题/html网页制作模板代码
  • 国外做问卷网站/制作网站公司
  • 赌博网站是怎么做的/b站不收费网站
  • 上海自适应网站开发/培训机构退费纠纷一般怎么解决
  • 郑州网站建设公司 艾特/幽默软文经典案例300
  • 深圳做棋牌网站建设哪家技术好/热门网站