class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
}
};
剑指 Offer II 107. 矩阵中的距离
给定一个由 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 <= 104
1 <= m * n <= 104
mat[i][j] is either 0 or 1.
mat
中至少有一个 0
注意:本题与主站 542 题相同:https://leetcode.cn/problems/01-matrix/
原站题解
python3 解法, 执行用时: 248 ms, 内存消耗: 17 MB, 提交时间: 2022-11-21 11:28:09
class Solution: def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]: m, n = len(matrix), len(matrix[0]) # 初始化动态规划的数组,所有的距离值都设置为一个很大的数 dist = [[10**9] * n for _ in range(m)] # 如果 (i, j) 的元素为 0,那么距离为 0 for i in range(m): for j in range(n): if matrix[i][j] == 0: dist[i][j] = 0 # 只有 水平向左移动 和 竖直向上移动,注意动态规划的计算顺序 for i in range(m): for j in range(n): if i - 1 >= 0: dist[i][j] = min(dist[i][j], dist[i - 1][j] + 1) if j - 1 >= 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 + 1 < m: dist[i][j] = min(dist[i][j], dist[i + 1][j] + 1) if j + 1 < n: dist[i][j] = min(dist[i][j], dist[i][j + 1] + 1) return dist
python3 解法, 执行用时: 488 ms, 内存消耗: 17.1 MB, 提交时间: 2022-11-21 11:27:52
class Solution: def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]: m, n = len(matrix), len(matrix[0]) # 初始化动态规划的数组,所有的距离值都设置为一个很大的数 dist = [[10**9] * n for _ in range(m)] # 如果 (i, j) 的元素为 0,那么距离为 0 for i in range(m): for j in range(n): if matrix[i][j] == 0: dist[i][j] = 0 # 只有 水平向左移动 和 竖直向上移动,注意动态规划的计算顺序 for i in range(m): for j in range(n): if i - 1 >= 0: dist[i][j] = min(dist[i][j], dist[i - 1][j] + 1) if j - 1 >= 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): if i + 1 < m: dist[i][j] = min(dist[i][j], dist[i + 1][j] + 1) if j - 1 >= 0: dist[i][j] = min(dist[i][j], dist[i][j - 1] + 1) # 只有 水平向右移动 和 竖直向上移动,注意动态规划的计算顺序 for i in range(m): for j in range(n - 1, -1, -1): if i - 1 >= 0: dist[i][j] = min(dist[i][j], dist[i - 1][j] + 1) if j + 1 < n: 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 + 1 < m: dist[i][j] = min(dist[i][j], dist[i + 1][j] + 1) if j + 1 < n: dist[i][j] = min(dist[i][j], dist[i][j + 1] + 1) return dist
python3 解法, 执行用时: 284 ms, 内存消耗: 18.8 MB, 提交时间: 2022-11-21 11:27:19
class Solution: def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]: m, n = len(matrix), len(matrix[0]) dist = [[0] * n for _ in range(m)] zeroes_pos = [(i, j) for i in range(m) for j in range(n) if matrix[i][j] == 0] # 将所有的 0 添加进初始队列中 q = collections.deque(zeroes_pos) seen = set(zeroes_pos) # 广度优先搜索 while q: i, j = q.popleft() for ni, nj in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]: if 0 <= ni < m and 0 <= nj < n and (ni, nj) not in seen: dist[ni][nj] = dist[i][j] + 1 q.append((ni, nj)) seen.add((ni, nj)) return dist
golang 解法, 执行用时: 48 ms, 内存消耗: 7.7 MB, 提交时间: 2022-11-21 11:26:47
func updateMatrix(matrix [][]int) [][]int { n, m := len(matrix), len(matrix[0]) queue := make([][]int, 0) for i := 0; i < n; i++ { // 把0全部存进队列,后面从队列中取出来,判断每个访问过的节点的上下左右,直到所有的节点都被访问过为止。 for j := 0; j < m; j++ { if matrix[i][j] == 0 { point := []int{i, j} queue = append(queue, point) } else { matrix[i][j] = -1 } } } direction := [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}} for len(queue) > 0 { // 这里就是 BFS 模板操作了。 point := queue[0] queue = queue[1:] for _, v := range direction { x := point[0] + v[0] y := point[1] + v[1] if x >= 0 && x < n && y >= 0 && y < m && matrix[x][y] == -1 { matrix[x][y] = matrix[point[0]][point[1]] + 1 queue = append(queue, []int{x, y}) } } } return matrix }