leetcode542 - 01 Matrix - medium

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.
Example 1:
Input:
0 0 0 0 0 0
0 1 0 -> 0 1 0
0 0 0 0 0 0
Example 2:
Input:
0 0 0 0 0 0
0 1 0 -> 0 1 0
1 1 1 1 2 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.

BFS。
先让所有的注水点O进q,接下来开始往1拓展,如果占到了就不能再让别人占了,因为先占到就说明是最近的,数字已经准了。
细节:
1.一定要所有O先一起入队,然后同时开始拓展搜索。本题不可以给每个O写个公用子函数bfs(),然后每个O都调用一次,如果看到别人占过的就更新一下。如果一共有n个点,这个方法不能保证每个点只被访问一次,而是会变成*O点个数次,从而整体时间复杂度为O(n^2),爆了O(n)了。
2.一圈一圈往外搜,要记录每圈的距离的时候,bfs要写的层级bfs,而不可以是stream bfs,否则dist就算错了。
3.bfs上下左右移动后一定要记得检查下标是否合格。
4.本题有一个省掉visited数组的小方法:需要visited的难点主要是难以区分1是来自于数组自带值还是已经访问过了距离确实是1.那么一开始遍历找0的时候顺便把所有1初始化为MAX_VALUE,那之后如果看到<MAX_VALUE的数字比如1的确就是因为已经访问过了赋值过值了,消除了歧义。

实现:

class Solution {
    public int[][] updateMatrix(int[][] matrix) {
        // P3: 这题不能让每个0都独立做一次bfs,然后遇到重复就更新,会TLE MLE。应该同时让所有O一起开始探索,谁先占到是谁的。
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return matrix;
        }
        
        int[] dx = {0, 1, 0, -1};
        int[] dy = {1, 0, -1, 0};
        boolean[][] isVisited = new boolean[matrix.length][matrix[0].length];
        Queue<Integer> qx = new LinkedList<>();
        Queue<Integer> qy = new LinkedList<>();

        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (matrix[i][j] == 0) {
                    qx.offer(i);
                    qy.offer(j);
                    isVisited[i][j] = true;
                }
            }
        }
        
        int dist = 0;
        while (!qx.isEmpty()) {             
            dist++;
            int size = qx.size();
            for (int cnt = 0; cnt < size; cnt++) {
                int cx = qx.poll();
                int cy = qy.poll();   
                for (int i = 0; i < 4; i++) {
                    int nx = cx + dx[i];
                    int ny = cy + dy[i];
                    // P1: 上下左右移动后一定要注意检查下标越界!!!
                    if (nx < 0 || nx >= matrix.length || ny < 0 
                        || ny >= matrix[0].length || isVisited[nx][ny]) {
                        continue;
                    }
                    matrix[nx][ny] = dist;
                    isVisited[nx][ny] = true;
                    qx.offer(nx);
                    qy.offer(ny);
                }
            }
        }
        return matrix;
    }

}

猜你喜欢

转载自www.cnblogs.com/jasminemzy/p/9644262.html