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

news2025/3/23 9:54:07

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
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2319248.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

雅可比行列式

定义和推导 雅可比行列式&#xff0c;它是以n个n元函数的偏导数为元素的行列式。以下是雅可比式的推导过程&#xff1a; 二阶雅可比式的推导以二重积分中的极坐标变换为例&#xff0c;设 &#xff1a; &#xff0c;则 x 和 y 的全微分分别为&#xff1a; 可以将 dx 与 dy 视作…

【大模型基础_毛玉仁】3.2 上下文学习

目录 3.2 上下文学习3.2.1 上下文学习的定义3.2.2 演示示例选择1&#xff09;直接检索2&#xff09;聚类检索3&#xff09;迭代检索 3.2.3 性能影响因素 3.2 上下文学习 随模型训练数据规模和参数量的扩大&#xff0c;大语言模型涌现出了上下文学习&#xff08;In-Context Lea…

Oraclelinux问题-/var/log/pcp/pmlogger/目录超大

有套19c rac环境&#xff0c;操作系统是oracle linux 8.10&#xff0c;日常巡检时发现/var/log/pcp/pmlogger/目录超大&#xff0c;如下 [rootdb1 ~]# du -sh /var/log/pcp/pmlogger/* 468G /var/log/pcp/pmlogger/db 1.3G /var/log/pcp/pmlogger/oracle06-106 754M /…

【大语言模型_8】vllm启动的模型通过fastapi封装增加api-key验证

背景&#xff1a; vllm推理框架启动模型不具备api-key验证。需借助fastapi可以实现该功能 代码实现&#xff1a; rom fastapi import FastAPI, Header, HTTPException, Request,Response import httpx import logging# 创建 FastAPI 应用 app FastAPI() logging.basicConfig(…

学习笔记 ASP.NET Core Web API 8.0部署到iis

一.修改配置文件 修改Program.cs配置文件将 if (app.Environment.IsDevelopment()) {app.UseSwagger();app.UseSwaggerUI(); }修改为 app.UseSwagger(); app.UseSwaggerUI(); 二.安装ASP.NET Core Runtime 8.0.14 文件位置https://dotnet.microsoft.com/en-us/download/do…

Microsoft Edge浏览器的取证分析(基于Chromium)

概述 早在2019年&#xff0c;微软就用Chromium替换了EdgeHTML浏览器引擎&#xff0c;这是微软支持谷歌Chrome浏览器的一个开源项目。通过切换到Chromium&#xff0c;Edge与Chrome浏览器共享一个共同的架构&#xff0c;这意味着用于Chrome浏览器调查的取证技术也适用于Edge。 …

汽车一键启动系统使用方便,舒适出行,轻松匹配

汽车一键启动系统 系统定义 移动管家汽车一键启动系统是装置在智能汽车上的一部分&#xff0c;是实现简约打火和熄火过程的一个按钮装置。它可以在原车钥匙锁头的位置改装&#xff0c;也能独立面板改装&#xff0c;现在很多高低配置的车辆都可安装。 功能特点 基本功能 启…

C语言复习笔记--数组

今天继续来浅浅推进一下C语言的复习,这次是数组的复习,话不多说,正文开始. 数组的概念 数组是⼀组相同类型元素的集合,一种自定义类型.数组中元素个数不能为0.数组分为⼀维数组和多维数组&#xff0c;多维数组⼀般⽐较多⻅的是⼆维数组. 下面从一维数组说起. 一维数组的创建和…

海康SDK协议在智联视频超融合平台中的接入方法

一. 海康SDK协议详解 海康SDK协议原理 海康SDK协议是海康威视为开发者提供的一套软件开发工具包&#xff0c;用于与海康设备&#xff08;如摄像头、NVR、DVR等&#xff09;进行通信和控制。其核心原理包括&#xff1a; 网络通信&#xff1a;基于TCP/IP协议&#xff0c;实现设…

腾讯云大模型知识引擎×DeepSeek:股票分析低代码应用实践

项目背景与发展历程 在金融科技快速发展的今天&#xff0c;股票分析作为投资决策的核心环节&#xff0c;正面临数据量激增和复杂性提升的挑战。传统股票分析依赖人工处理&#xff0c;效率低下且成本高昂&#xff0c;而人工智能&#xff08;AI&#xff09;的引入为这一领域带来…

【工具】C#防沉迷进程监控工具使用手册

一、软件简介 本工具用于监控指定进程的运行时长&#xff0c;当达到预设时间时通过声音、弹窗、窗口抖动等方式进行提醒&#xff0c;帮助用户合理控制程序使用时间。 软件在上篇文章。 二、系统要求 Windows 7/10/11.NET Framework 4.5 或更高版本 三、快速入门 1. 配置文件…

【docker】--- 详解 WSL2 中的 Ubuntu 和 Docker Desktop 的区别和关系!

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。【WSL 】--- Windows11 迁移 WSL 超详细指南 —— 给室友换一个宿舍! 开发环境一、引…

强大的AI网站推荐(第一集)—— Devv AI

网站&#xff1a;Devv AI 号称&#xff1a;最懂程序员的新一代 AI 搜索引擎 博主评价&#xff1a;我的大学所有的代码都是使用它&#xff0c;极大地提升了我的学习和开发效率。 推荐指数&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x…

模块二 单元4 安装AD+DC

模块二 单元4 安装ADDC 两个任务&#xff1a; 1.安装AD活动目录 2.升级当前服务器为DC域控制器 安装前的准备工作&#xff1a; 确定你要操作的服务器系统&#xff08;Windows server 2022&#xff09;&#xff1b; 之前的服务器系统默认是工作组的模式workgroup模式&#xff08…

蓝桥杯备考:数学问题模运算---》次大值

这道题&#xff0c;由于数据规模是2e5&#xff0c;我们直接暴力的话是一定会超时的 所以我们得想个办法&#xff0c;我们先把所有的数排序去重 我们先想想如果要找最大值&#xff0c;怎么找 这时候我们要分类讨论 ①如果是大数模小数&#xff0c;那结果肯定是小于小数的&am…

k8s1.30 部署calio网络

一、介绍 网路组件有很多种&#xff0c;只需要部署其中一个&#xff0c;推荐calio。 calio是一个纯三成的数据中心网络方案&#xff0c;calico支持广泛的平台。如k8s&#xff0c;openstack等。 calio在每一个计算节点利用linux内核&#xff0c;实现了一个高效的虚拟路由器来…

Elasticsearch:为推理端点配置分块设置

推理端点对一次可处理的文本量有限&#xff0c;具体取决于模型的输入容量。分块&#xff08;Chunking&#xff09; 是指将输入文本拆分成符合这些限制的小块的过程&#xff0c;在将文档摄取到 semantic_text 字段时会进行分块。分块不仅有助于保持输入文本在可处理范围内&#…

[工控机安全] 使用DriverView快速排查不可信第三方驱动(附详细图文教程)

导语&#xff1a; 在工业控制领域&#xff0c;设备驱动程序的安全性至关重要。第三方驱动可能存在兼容性问题、安全漏洞甚至恶意代码&#xff0c;威胁设备稳定运行。本文将手把手教你使用 DriverView工具&#xff0c;高效完成工控机驱动安全检查&#xff0c;精准识别可疑驱动&a…

多无人车协同探索开源包启动文件介绍(上)

在之前介绍的《多无人车协同探索开源包部署教程及常见报错解决方式》中运行多无人车协同探索时&#xff0c;先后运行了两个launch文件 multiple_tb3_house.launch 和three_robots.launch &#xff0c;本文来进一步看一下这两个启动文件以及其调用的move_base .launch 和multi_t…

Linux驱动学习笔记(三)

并发与竞争 1.在编写驱动程序的时候&#xff0c;要尽量避免让驱动程序存在并发和竞争&#xff0c;Linux内核里面提供了几种处理并发与竞争的方法&#xff0c;分别是&#xff1a;原子操作、自旋锁、信号量和互斥体。 原子操作&#xff1a;Linux的原子操作基于atomic_t数据类型…