542. 01 矩阵
中 等 \color{#FFB800}{中等} 中等
给定一个由
0和1组成的矩阵mat,请输出一个大小相同的矩阵,其中每一个格子是mat中对应位置元素到最近的0的距离。
两个相邻元素间的距离为1。
示例 1:

输入:mat = [[0,0,0],[0,1,0],[0,0,0]]
输出:[[0,0,0],[0,1,0],[0,0,0]]
示例 2:

输入:mat = [[0,0,0],[0,1,0],[1,1,1]]
输出:[[0,0,0],[0,1,0],[1,2,1]]
提示:
m == mat.lengthn == mat[i].length- 1 <= m, n <= 104
- 1 <= m * n <= 104
mat[i][j] is either 0 or 1.mat中至少有一个0
方法1:多源广度优先搜索
我们先关注普通的广度优先搜索。先假设地图中有且仅有一个0。
题目中提到,每一个格子是 mat 中对应位置元素到最近的 0 的距离,那么反过来,每一个格子的值是0到这个元素的距离。这样一来,我们的出发点就清晰多了。我们可以从值为0的土地出发进行广度优先搜索,每次向外扩展时,土地周围的4块土地值为1;然后从值为1的土地向周围4个格子扩展,周围土地的值为2,以此类推。第i轮中遍历出来的所有土地的值也是i(这里的i从1开始计数)。
以一块4x4的mat为例,其中(1,1)处为0,过程如下:
_ _ _ _ _ 1 _ _ 2 1 2 _ 2 1 2 3 2 1 2 3
_ 0 _ _ ==> 1 0 1 _ ==> 1 0 1 2 ==> 1 0 1 2 ==> 1 0 1 2
_ _ _ _ _ 1 _ _ 2 1 2 _ 2 1 2 3 2 1 2 3
_ _ _ _ _ _ _ _ _ 2 _ _ 3 2 3 _ 3 2 3 4
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/01-matrix/solution/01ju-zhen-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
上述示例来自LeetCode官方题解
此外,我们还需要一个数组seen来存储哪些土地被访问过了,以免再次被加入到队列中。例如下方的例子:
1 _ _
0 1 _
1 _ _
我们已经从左边的0扩展到了中间的1,接下来我们应该往“上右下”3个方向扩展,左侧应该被忽略。
我们其实在【LeetCode学习计划】《算法-入门-C++》第7天 广度优先搜索 / 深度优先搜索这篇文章中的733. 图像渲染和695. 岛屿的最大面积这两道题,已经遇到过用于记录土地是否访问过的数组了。这两道题中,由于我们遍历完的土地已经不需要了,所以土地的值被设为了0,而这个“值设为0”的操作就相当于我们对这块土地记为已访问过的操作。用于记录是否被访问过的数组被我们抽象到地图本身了。而这一题,我们最后的结果都是有用的,所以不能抛弃。
当然,你可以作一次判断,如果即将赋予的值小于土地当前的值,那么就覆盖原值并加入队列重新扩展,但那样就太扯了。假设你的矩阵里全是0,而且按照这个思路,对于每一个0都要将整个矩阵遍历一次。将整个矩阵赋值完成后,因为不能确定每个土地的值到自己近还是到别的0近,下一个0又要将整个(几乎)矩阵重新遍历一次,。看一下下面的例子:
0 0 0 0 0 1 2 3 0 0 1 2 0 0 0 0 0 0 0 0
0 0 0 0 => 1 2 3 4 => 1 1 2 3 => ... => 0 1 1 1 => 0 0 1 1
0 0 0 0 2 3 4 5 2

最低0.47元/天 解锁文章
454

被折叠的 条评论
为什么被折叠?



