【LeetCode学习计划】《算法-入门-C++》第9天 广度优先搜索 / 深度优先搜索



542. 01 矩阵

LeetCode

中 等 \color{#FFB800}{中等}

给定一个由 01 组成的矩阵 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.length
  • n == 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亡心灵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值