📌  相关文章
📜  二进制矩阵中距任何0个像元最接近的1个像元的所有距离的最大值(1)

📅  最后修改于: 2023-12-03 15:06:20.634000             🧑  作者: Mango

二进制矩阵中距任何0个像元最接近的1个像元的所有距离的最大值
问题描述

给定一个 01 矩阵 mat,找到每个元素到最近的 0 的距离。

两个相邻元素间的距离为 1 。我们可以假设矩阵中有多个 0。

例如,对于矩阵 mat = [[0, 0, 0], [0, 1, 0], [0, 0, 0]],最近的 0 的距离如下:

[[0, 0, 0], [0, 1, 0], [0, 0, 0]]

可以表示为:

[[0, 0, 0], [0, 1, 0], [0, 0, 0]]

又例如,对于矩阵 mat = [[0, 0, 0], [0, 1, 0], [1, 1, 1]],最近的 0 的距离如下:

[[0, 0, 0], [0, 1, 0], [1, 2, 1]]

可以表示为:

[[0, 0, 0], [0, 1, 0], [1, 2, 1]]

解题思路

思路一:广度优先搜索 BFS

从每一个 0 出发,进行广度优先搜索。

首先遍历矩阵,将值为 0 的点加入队列,然后从队列中依次取出点,并将其周围四个点的值更新为当前点的值加 1。

以此循环,直到队列为空,则更新完成。

时间复杂度:O(m*n * (m+n)),其中 m 和 n 分别为矩阵的行数和列数。

空间复杂度:O(m*n),其中 m 和 n 分别为矩阵的行数和列数。

思路二:动态规划

定义一个距离矩阵 dist,其中 dist[i][j] 表示从位置 (i, j) 到最近的 0 的距离。对于每个点 (i, j),初始化 dist[i][j]=∞,然后dist[i][j] 不断被更新为 min(dist[i][j], dist[i-1][j], dist[i][j-1], dist[i+1][j], dist[i][j+1])+1。

以此循环,直到不再有发生变化的点,则更新完成。

时间复杂度:O(m*n),其中 m 和 n 分别为矩阵的行数和列数。

空间复杂度:O(m*n),其中 m 和 n 分别为矩阵的行数和列数。

代码实现
  1. 广度优先搜索 BFS
from collections import deque

class Solution:
    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:
        m, n = len(mat), len(mat[0])
        dist = [[0] * n for _ in range(m)]
        q = deque()
        for i in range(m):
            for j in range(n):
                if mat[i][j] == 0:
                    q.append((i, j))
                else:
                    dist[i][j] = float('inf')
        dirs = [(-1, 0), (0, -1), (1, 0), (0, 1)] # 上下左右
        while q:
            x, y = q.popleft()
            for dx, dy in dirs:
                nx, ny = x + dx, y + dy
                if 0 <= nx < m and 0 <= ny < n and dist[nx][ny] > dist[x][y] + 1:
                    dist[nx][ny] = dist[x][y] + 1
                    q.append((nx, ny))
        return dist
  1. 动态规划
class Solution:
    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:
        m, n = len(mat), len(mat[0])
        dist = [[0 if mat[i][j] == 0 else float('inf') for j in range(n)] for i in range(m)]
        # 从左上角开始
        for i in range(m):
            for j in range(n):
                if i > 0:
                    dist[i][j] = min(dist[i][j], dist[i-1][j] + 1)
                if j > 0:
                    dist[i][j] = min(dist[i][j], dist[i][j-1] + 1)
        # 从右下角开始
        for i in range(m-1, -1, -1):
            for j in range(n-1, -1, -1):
                if i < m-1:
                    dist[i][j] = min(dist[i][j], dist[i+1][j] + 1)
                if j < n-1:
                    dist[i][j] = min(dist[i][j], dist[i][j+1] + 1)
        return dist