【LeetCode】 01矩阵 (BFS/DFS)

8## 【LeetCode】 01矩阵 (BFS/DFS)
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离
两个相邻元素间的距离为 1 。

示例 1:

输入:
0 0 0
0 1 0
0 0 0
输出:
0 0 0
0 1 0
0 0 0

示例 2:

输入:
0 0 0
0 1 0
1 1 1
输出:
0 0 0
0 1 0
1 2 1

一、广度优先搜索(树的BFS与图的BFS)
思路:
对于 「Tree 的 BFS」 (典型的「单源 BFS」) 大家都已经轻车熟路了:
首先把 root 节点入队,再一层一层无脑遍历就行了。
对于 「图 的 BFS」 (「多源 BFS」) 做法其实也是一样滴~,与 「Tree 的 BFS」的区别注意以下两条就 ok 辣~
Tree 只有 1 个 root,而图可以有多个源点,所以首先需要把多个源点都入队;
Tree 是有向的因此不需要标识是否访问过,而对于无向图来说,必须得标志是否访问过哦!并且为了防止某个节点多次入队,需要在其入队之前就将其设置成已访问!【 看见很多人说自己的 BFS 超时了,坑就在这里哈哈哈
做法:
根据上述思路,本题怎么做就很简单了:
首先把每个源点 0 入队,然后从各个 0 同时开始一圈一圈的向 1 扩散(每个 1 都是被离它最近的 0 扩散到的 ),扩散的时候可以设置 int[][] dist 来记录距离(即扩散的层次)并同时标志是否访问过。对于本题是可以直接修改原数组 int[][] matrix 来记录距离和标志是否访问的,这里要注意先把 matrix 数组中 1 的位置设置成 -1 (设成Integer.MAX_VALUE啦,m * n啦,10000啦都行,只要是个无效的距离值来标志这个位置的 1 没有被访问过就行辣~)

	public int[][] updateMatrix(int[][] matrix) {
         // 首先将所有的 0 都入队,并且将 1 的位置设置成 -1,表示该位置是 未被访问过的 1
	        Queue<int[]> queue = new LinkedList<>();
	        int m = matrix.length, n = matrix[0].length;
	        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] = -1;
	                } 
	            }
	        }
	        int[] dx = new int[] {-1, 1, 0, 0};
	        int[] dy = new int[] {0, 0, -1, 1};
	        while (!queue.isEmpty()) {
	            int[] point = queue.poll();
	            int x = point[0], y = point[1];
	            for (int i = 0; i < 4; i++) {
	                int newX = x + dx[i];
	                int newY = y + dy[i];
	                // 如果四邻域的点是 -1,表示这个点是未被访问过的 1
	                // 所以这个点到 0 的距离就可以更新成 matrix[x][y] + 1。
	                if (newX >= 0 && newX < m && newY >= 0 && newY < n 
	                        && matrix[newX][newY] == -1) {
	                    matrix[newX][newY] = matrix[x][y] + 1;
	                    queue.offer(new int[] {newX, newY});
	                }
	            }
	        }
	        return matrix;
    }

二、深度优先搜索(DFS)

	private int row;
    private int col;
    private int[][] vector = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

    public int[][] updateMatrix(int[][] matrix) {
        row = matrix.length;
        col = matrix[0].length;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                // 优化:如果元素在 0 附近,保留元素值 1,不在 0 附近,初始化为一个较大值
                if (matrix[i][j] == 1
                        && !((i > 0 && matrix[i - 1][j] == 0)
                        || (i < row - 1 && matrix[i + 1][j] == 0)
                        || (j > 0 && matrix[i][j - 1] == 0)
                        || (j < col - 1 && matrix[i][j + 1] == 0))) {
                    matrix[i][j] = row + col;
                }
            }
        }
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                // 优化:将元素值为 1 的点作为深搜起点,降低递归深度
                if (matrix[i][j] == 1) {
                    DFS(matrix, i, j);
                }
            }
        }
        return matrix;
    }

    private void DFS(int[][] matrix, int r, int c) {
        // 搜索上下左右四个方向
        for (int[] v : vector) {
            int nr = r + v[0], nc = c + v[1];
            if (nr >= 0 && nr < row
                    && nc >= 0 && nc < col
                    && matrix[nr][nc] > matrix[r][c] + 1) {
                matrix[nr][nc] = matrix[r][c] + 1;
                DFS(matrix, nr, nc);
            }
        }
    }

作者:sweetiee
链接:https://leetcode-cn.com/problems/01-matrix/solution/2chong-bfs-xiang-jie-dp-bi-xu-miao-dong-by-sweetie/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值