[LeetCode] 542. 01 Matrix

Given an m x n binary matrix mat, return the distance of the nearest 0 for each cell.

The distance between two adjacent cells is 1.

Note:

  1. The number of elements of the given matrix will not exceed 10,000.
  2. There are at least one 0 in the given matrix.
  3. The cells are adjacent in only four directions: up, down, left and right.

Example 1:

Input:
[[0,0,0],
 [0,1,0],
 [0,0,0]]

Output:
[[0,0,0],
 [0,1,0],
 [0,0,0]]

Example 2:

Input:
[[0,0,0],
 [0,1,0],
 [1,1,1]]

Output:
[[0,0,0],
 [0,1,0],
 [1,2,1]]

01矩阵。

给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。

两个相邻元素间的距离为 1 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/01-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这是一道 flood fill 类型的搜索题目,在二维矩阵里面找题目规定的东西。因为是在矩阵里找最短距离,所以思路是 BFS。首先将所有值为 0 的元素都加入 queue,再将所有不为 0 的元素全都标记成 Integer.MAX_VALUE。然后按照 BFS 的正常思路遍历 queue 中的每个点。在从 queue 中弹出每个点的时候,我们先通过 queue 拿到这个点四个方向的邻居坐标。对于每个邻居坐标,我们判断

  • 是否越界,越界的话就跳过
  • 如果邻居坐标的坐标值是 Integer.MAX_VALUE,说明这个值没有被访问过,这个坐标值需要被更新成当前坐标值 + 1

处理完了这些 case 之后,被加入 queue 的应该只有可能是一开始被标记成 Integer.MAX_VALUE 的坐标值了。如果这些点在某一次扫描中被发现了,他们就会被标记他邻居节点的节点值 + 1 然后再次放入 queue。

这个做法巧妙的地方在于先将值为 1 的坐标改成 Integer.MAX_VALUE,这样越靠近 0 的点会被越先改成 1。被改成 1 的坐标旁边如果还有 Integer.MAX_VALUE,会在被找到之后再被赋值为 1 + 1 = 2。参考第二个例子。所以与其是找每个 1 附近最近的 0,可以把题目理解成找每个 0 附近最近的 1。

时间 O(mn)

空间 O(mn) - worse case 可能所有元素都要经过一遍 queue

Java实现

 1 class Solution {
 2     public int[][] updateMatrix(int[][] mat) {
 3         int m = mat.length;
 4         int n = mat[0].length;
 5         Queue<int[]> queue = new LinkedList<>();
 6         for (int i = 0; i < m; i++) {
 7             for (int j = 0; j < n; j++) {
 8                 if (mat[i][j] == 0) {
 9                     queue.offer(new int[] { i, j });
10                 } else {
11                     mat[i][j] = Integer.MAX_VALUE;
12                 }
13             }
14         }
15 
16         int[][] DIRS = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
17         while (!queue.isEmpty()) {
18             int[] point = queue.poll();
19             int x = point[0];
20             int y = point[1];
21             for (int[] dir : DIRS) {
22                 int r = x + dir[0];
23                 int c = y + dir[1];
24                 // 坐标在矩阵内同时坐标没有被访问过
25                 if (r >= 0 && r < m && c >= 0 && c < n && mat[r][c] == Integer.MAX_VALUE) {
26                     mat[r][c] = mat[x][y] + 1;
27                     queue.offer(new int[] { r, c });
28                 }
29             }
30         }
31         return mat;
32     }
33 }

 

相关题目

286. Walls and Gates

542. 01 Matrix

1730. Shortest Path to Get Food

flood fill题型总结

LeetCode 题目总结

posted @ 2020-04-16 12:07  CNoodle  阅读(165)  评论(0编辑  收藏  举报