LC 墙与门

image.png

输入: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,优先访问当前结点相邻的点,如下图所示,数字表示访问的顺序


BFS.png

简单的来说:

  1. 先访问1,然后23待命
  2. 1访问完,访问2,此时与2相邻的45也加入待命的队列,这时候待访问的有345
  3. 2访问完,访问3(23与1相邻),接着56加入待命的队列,此时待访问的有456
  4. 与1相邻的访问完了,下面访问4,7加入待访问队列,待访问的有567
  5. 同理,5访问完,待访问的有678
  6. 6访问完,待访问的有7、8
  7. 7 访问完,待访问的有8、9、10
  8. 8访问完,待访问的有9、10、 11
  9. 剩下的就按顺序访问完
    所以bfs就像走一棵树一样,一层一层访问,待访问的点都是推与当前点相邻结点。

回到本题目,我们要找到,每个空格离门最近的距离,那不就相当于我们从门到空格经历了几层吗。拿示例1举个


image.png

从左下角的门,我们只能向上走一步(右边是墙走不通),因此门上一空格为①,接着走,我们只能再往上走(右边是墙),因此门上二空格为②,再从这个空格我们继续往四周走,可以向上,向右走,因此这两个空格我标③,就这么一直走,像树蔓延一样,我们得到了每个空格离左下门的距离(左图)。
我们用相同的方法走右上的门,标出每个空格离右上们的距离(右图)。
最后比较一下每个空格的数字大小,留下数字小的,就是离门最近的距离。
总之,四个方向,遇到墙走不通,不回头。

代码逻辑:

  1. 找grid[i][j] == 0,做bfs的递归,注意边界,只要你往下走就做一层递归,step+1
  2. 如果rooms[i][j]<=step,就不要继续往下走了
  3. 多个门,只要你当前的step是小于已经记录下来的rooms[i][j],那就替换

你可能感兴趣的:(LC 墙与门)