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

LeetCode题练习与总结:01 矩阵--542

一、题目描述

给定一个由 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 <= 10^4
  • 1 <= m * n <= 10^4
  • mat[i][j] is either 0 or 1.
  • mat 中至少有一个 

二、解题思路

这个问题可以通过多源广度优先搜索(BFS)来解决。解题思路如下:

  1. 创建一个队列,用于存放所有的0的位置,这些位置是起点。
  2. 从这些起点开始,进行层序遍历,每一层的遍历都是距离起点的距离加1。
  3. 对于每个遍历到的1,更新其距离为当前层的距离。
  4. 遍历完成后,返回更新后的矩阵。

三、具体代码

import java.util.LinkedList;
import java.util.Queue;

class Solution {
    public int[][] updateMatrix(int[][] mat) {
        int m = mat.length;
        int n = mat[0].length;
        int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
        Queue<int[]> queue = new LinkedList<>();
        
        // 初始化队列,将所有的0的位置加入队列
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (mat[i][j] == 0) {
                    queue.offer(new int[]{i, j});
                } else {
                    // 将1的位置初始化为最大值,表示尚未访问
                    mat[i][j] = Integer.MAX_VALUE;
                }
            }
        }
        
        // 开始层序遍历
        while (!queue.isEmpty()) {
            int[] current = queue.poll();
            int x = current[0];
            int y = current[1];
            
            // 遍历四个方向
            for (int[] direction : directions) {
                int newX = x + direction[0];
                int newY = y + direction[1];
                
                // 检查新位置是否在矩阵范围内,并且新位置的值可以更新
                if (newX >= 0 && newX < m && newY >= 0 && newY < n && mat[newX][newY] > mat[x][y] + 1) {
                    mat[newX][newY] = mat[x][y] + 1;
                    queue.offer(new int[]{newX, newY});
                }
            }
        }
        
        return mat;
    }
}

这段代码首先将所有的0的位置加入队列,并将所有的1的位置设置为Integer.MAX_VALUE。然后,从队列中取出元素,遍历其四个方向,如果新位置在矩阵范围内并且新位置的值可以更新(即比当前值大),则更新新位置的值,并将其加入队列。最终,队列为空时,所有位置的距离都已经被正确更新。

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 初始化队列时,我们需要遍历整个矩阵,这个步骤的时间复杂度是 O(m * n),其中 m 是矩阵的行数,n 是矩阵的列数。
  • 在层序遍历过程中,每个元素最多只会被加入队列一次,因此队列中的元素数量最多是 m * n。每次从队列中取出一个元素,并对其四个方向进行遍历,这一步的时间复杂度是 O(4),因为每个元素最多有四个相邻元素。
  • 因此,层序遍历的总时间复杂度是 O(m * n),因为每个元素都会被处理一次。

综上所述,总的时间复杂度是 O(m * n) + O(m * n) = O(m * n)。

2. 空间复杂度
  • 队列的大小取决于矩阵中0的个数,在最坏的情况下,如果矩阵全为0,则队列的大小将是 m * n。
  • 我们使用了额外的 directions 数组来表示四个方向,这个数组的大小是常数,因此它对空间复杂度的影响是 O(1)。
  • 我们在原矩阵上进行更新,没有使用额外的矩阵来存储结果,因此除了队列之外,没有使用额外的空间。

综上所述,总的空间复杂度是 O(m * n),这是在最坏情况下队列的最大空间需求。

五、总结知识点

  1. 类定义class Solution 定义了一个名为 Solution 的类。

  2. 成员方法public int[][] updateMatrix(int[][] mat) 定义了一个公共方法,该方法接收一个二维整数数组 mat 作为参数,并返回一个同样类型的数组。

  3. 二维数组int[][] mat 是一个二维整数数组,用于表示给定的矩阵。

  4. 队列的使用Queue<int[]> queue = new LinkedList<>(); 创建了一个队列,用于在广度优先搜索(BFS)中存储待处理的元素。

  5. 数组的初始化int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; 初始化了一个二维数组,表示四个可能的移动方向(右、左、下、上)。

  6. 嵌套循环:两个嵌套的 for 循环用于遍历矩阵的每个元素。

  7. 条件语句if 语句用于检查矩阵中的元素是否为0,以及更新矩阵中的元素值。

  8. 队列操作queue.offer(new int[]{i, j}); 将元素加入队列,queue.poll(); 从队列中取出元素。

  9. 边界检查if (newX >= 0 && newX < m && newY >= 0 && newY < n) 用于确保新的坐标在矩阵的边界内。

  10. 矩阵更新mat[newX][newY] = mat[x][y] + 1; 更新矩阵中元素的距离值。

  11. 常量Integer.MAX_VALUE 是一个整型常量,表示整型可以表示的最大值,用于初始化矩阵中的1的位置。

  12. 广度优先搜索(BFS):整个方法的核心是使用BFS算法来计算每个元素到最近的0的距离。

  13. 返回值return mat; 返回更新后的矩阵。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。


http://www.kler.cn/a/503888.html

相关文章:

  • 【2025 Rust学习 --- 17 文本和格式化 】
  • 【Rust自学】12.6. 使用TDD(测试驱动开发)开发库功能
  • 学英语学Elasticsearch:04 Elastic integrations 工具箱实现对第三方数据源的采集、存储、可视化,开箱即用
  • LeetCode-493. Reverse Pairs
  • Apache JMeter 压力测试使用说明
  • 【ARM】MDK如何将变量存储到指定内存地址
  • 构建优雅、高效的 Nodejs 命令行工具 - Archons
  • day13-第一次摸底考试题及讲解
  • L2 正则化(权重衰减)
  • 优化 MySQL 的慢查询
  • WPF系列十二:图形控件CombinedGeometry
  • 42_Lua table表
  • 【拒绝算法PUA】3065. 超过阈值的最少操作数 I
  • Spring Boot 2 学习全攻略
  • w~大模型~合集27
  • 托宾效应和托宾q理论。简单解释
  • uniapp 发布后原生img正常,image无法显示,img与uniapp image使用区别
  • 【Block总结】Conv2Former的Block,结合卷积网络和Transformer的优点|即插即用
  • 视频超分(VSR)论文阅读记录/idea积累(一)
  • 【学术会议指南】方向包括遥感、测绘、图像处理、信息化教育、计算机技术、通信、大数据、人工智能、机械设计、仿真...可线上参与
  • Oracle重启后业务连接大量library cache lock
  • 【web靶场】之upload-labs专项训练(基于BUUCTF平台)
  • 工程师 - Eclipse安装和UML插件
  • 代码随想录刷题day07|(数组篇)58.区间和
  • LeetCode 热题 100_从前序与中序遍历序列构造二叉树(47_105_中等_C++)(二叉树;递归)
  • AI-ANNE:探索型神经网络——将深度学习模型转移到微控制器和嵌入式系统