输入:rooms = [[2147483647,-1,0,2147483647],[2147483647,2147483647,2147483647,-1],[2147483647,-1,2147483647,-1],[0,-1,2147483647,2147483647]]
输出:[[3,-1,0,1],[2,2,1,-1],[1,-1,2,-1],[0,-1,3,4]]
示例 2:
输入:rooms = [[-1]]
输出:[[-1]]
示例 3:
输入:rooms = [[2147483647]]
输出:[[2147483647]]
示例 4:
输入:rooms = [[0]]
输出:[[0]]
Solution:
class Solution:
def wallsAndGates(self, rooms: List[List[int]]) -> None:
"""
Do not return anything, modify rooms in-place instead.
"""
row = len(rooms)
col = len(rooms[0])
def bfs(i, j, step):
nonlocal row, col
if i < 0 or i > row -1 or j < 0 or j > col - 1:
return
if rooms[i][j] <= step and step != 0 :
return
rooms[i][j] = step
bfs(i + 1, j, step + 1)
bfs(i, j + 1, step + 1)
bfs(i - 1, j, step + 1)
bfs(i, j - 1, step + 1)
for i in range(row):
for j in range(col):
if rooms[i][j] == 0:
bfs(i, j, 0)
解题思路:
本题目主要考察bfs(广度优先搜索),一般这种找最短距离的,用bfs比较直观。那么什么是BFS呢,Breadth First Search,优先访问当前结点相邻的点,如下图所示,数字表示访问的顺序
简单的来说:
- 先访问1,然后23待命
- 1访问完,访问2,此时与2相邻的45也加入待命的队列,这时候待访问的有345
- 2访问完,访问3(23与1相邻),接着56加入待命的队列,此时待访问的有456
- 与1相邻的访问完了,下面访问4,7加入待访问队列,待访问的有567
- 同理,5访问完,待访问的有678
- 6访问完,待访问的有7、8
- 7 访问完,待访问的有8、9、10
- 8访问完,待访问的有9、10、 11
- 剩下的就按顺序访问完
所以bfs就像走一棵树一样,一层一层访问,待访问的点都是推与当前点相邻结点。
回到本题目,我们要找到,每个空格离门最近的距离,那不就相当于我们从门到空格经历了几层吗。拿示例1举个
从左下角的门,我们只能向上走一步(右边是墙走不通),因此门上一空格为①,接着走,我们只能再往上走(右边是墙),因此门上二空格为②,再从这个空格我们继续往四周走,可以向上,向右走,因此这两个空格我标③,就这么一直走,像树蔓延一样,我们得到了每个空格离左下门的距离(左图)。
我们用相同的方法走右上的门,标出每个空格离右上们的距离(右图)。
最后比较一下每个空格的数字大小,留下数字小的,就是离门最近的距离。
总之,四个方向,遇到墙走不通,不回头。
代码逻辑:
- 找grid[i][j] == 0,做bfs的递归,注意边界,只要你往下走就做一层递归,step+1
- 如果rooms[i][j]<=step,就不要继续往下走了
- 多个门,只要你当前的step是小于已经记录下来的rooms[i][j],那就替换