转载自:套路大解密:搞懂题目考察什么,剩下的任务就是套模板!
如果你经常在想为什么别人做题那么快,其实答案很简单:一是要快速明白过来这个题在考察什么,这需要对常用的数据结构和算法的适用场景很熟悉;二是要背模板!
没错,大神也需要背模板!当然,是理解着背,不是死记硬背!
下面,我就按照这个思路给大家展示,如何快速解决这个题。
这个题想考察什么?
虽然题目千变万化,但是考察点永远是那几个。本题给出了一个场景:求 每个 1 到 0 的最短的曼哈顿距离。其中曼哈顿距离就是只能沿着横、竖到达另外一个点走的步数。
在一个图中,能从一个点出发求这种最短距离的方法很容易想到就是 BFS,BFS 的名称是广度优先遍历,即把周围这一圈搜索完成之后,再搜索下一圈,是慢慢扩大搜索范围的。
图左边是BFS,按照层进行搜索;图右边是 DFS,先一路走到底,然后再回头搜索。
题目给出了多个1,要找出每个1到0的最近曼哈顿距离。由于1到0的距离和0到1的距离一样的,所以其实我们可以换个思维:找出每个0到1的距离。
因此,题目可以抽象成:多个起始点的BFS。恭喜你已经解决了一半问题。
剩下的任务就是套模板!
BFS 使用队列,把每个还没有搜索到的点依次放入队列,然后再弹出队列的头部元素当做当前遍历点。BFS 总共有两个模板:
- 如果不需要确定当前遍历到了哪一层,BFS 模板如下。
while queue 不空:
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未访问过:
queue.push(该节点)
- 如果要确定当前遍历到了哪一层,BFS 模板如下(层次遍历)。
这里增加了 level 表示当前遍历到二叉树中的哪一层了,也可以理解为在一个图中,现在已经走了多少步了。size 表示在当前遍历层有多少个元素,也就是队列中的元素数,我们把这些元素一次性遍历完,即把当前层的所有元素都向外走了一步。
level = 0
while queue 不空:
size = queue.size()
while (size --) {
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未被访问过:
queue.push(该节点)
}
level ++;
上面两个是通用模板,在任何题目中都可以用,是要记住的!
上面说了这个题(力扣第542题:01矩阵)是多个起始点的 BFS,不要害怕,就是需要先遍历一遍矩阵,把所有 0 先放进队列中,然后再利用模板二。
至此,把上面的思路套进模板,题目就能解决了。