> For the complete documentation index, see [llms.txt](https://hao-fu-1.gitbook.io/oj/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hao-fu-1.gitbook.io/oj/search/sao-ge/01-matrix.md).

# 01 Matrix

<https://leetcode.com/problems/01-matrix/description/>

> Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.
>
> The distance between two adjacent cells is 1.

## Thoughts

很直观的一个想法是依次以不为0的点为起点做BFS, 当每个点遇到一个为0的点则把距离记下, 停止搜索并切换到下一个点重复此过程.\
后来看到大神的做法, 是把所有为0的点压入queue中, 然后一起开始遍历. 每次把遇到的非INF点设为当前遍历的层数, 并停止继续往下的遍历, 因为对于该点, 现在的层数是最短的.\
这么做大大提升了搜索效率, 因此原来的方法会每个1节点都把附近的非0点再遍历一次. 是O(M^2N^2)复杂度, 高了一个数量级.

## Code

```
class Solution {
    public int[][] updateMatrix(int[][] matrix) {
        int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        int m = matrix.length, n = matrix[0].length;
        Set<int[]> starters = new HashSet<>();
        Queue<int[]> queue = new LinkedList<>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == 0) {
                    queue.offer(new int[]{i, j});
                } else {
                    matrix[i][j] = Integer.MAX_VALUE;
                }
            }
        }

        int level = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int[] pos = queue.poll();
                for (int[] dir : dirs) {
                    int x = pos[0] + dir[0];
                    int y = pos[1] + dir[1];
                    if (x >= 0 && x < m && y >= 0 && y < n && matrix[x][y] != 0) {
                        if (matrix[x][y] == Integer.MAX_VALUE) {
                            queue.add(new int[]{x, y});
                            matrix[x][y] = level + 1;
                        } 
                    } 
                }
            }
            level++;
        }

        return matrix;
    }
}
```

## Analysis

时间复杂度O(MN). M行N列. 因为每个节点都会最先被离得最近的0标记, 也就是说未来即使有其它点访问到也不会继续遍历, 因此每个节点只会被放入queue一次. 或者说每个点只会被放入queue一次.
