• 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;
        }
    
    }
  • 相关阅读:
    生成本地测试用https证书,支持通配符和多域名,初学OpenSSL
    SuperSocket.WebSocket.WebSocketServer.Setup无法启动
    CSS 特殊属性介绍之 pointer-events
    关于面试题 Array.indexof() 方法的实现及思考
    关于 CSS 反射倒影的研究思考
    Carousel 旋转画廊特效的疑难杂症
    有趣的 CSS 像素艺术
    视差滚动技术的简介及运用
    Yeoman 官网教学案例:使用 Yeoman 构建 WebApp
    展望未来:使用 PostCSS 和 cssnext 书写 CSS
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/9644262.html
Copyright © 2020-2023  润新知