zoukankan      html  css  js  c++  java
  • leetcode542

    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;
        }
    
    }
  • 相关阅读:
    bzoj 1176 cdq分治套树状数组
    Codeforces 669E cdq分治
    Codeforces 1101D 点分治
    Codeforces 1100E 拓扑排序
    Codeforces 1188D Make Equal DP
    Codeforces 1188A 构造
    Codeforces 1188B 式子转化
    Codeforces 1188C DP 鸽巢原理
    Codeforces 1179D 树形DP 斜率优化
    git commit -m "XX"报错 pre -commit hook failed (add --no-verify to bypass)问题
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/9644262.html
Copyright © 2011-2022 走看看