LeetCode-Python-286. 墙与门

654 篇文章 23 订阅

你被给定一个 m × n 的二维网格,网格中有以下三种可能的初始化值:

-1 表示墙或是障碍物
0 表示一扇门
INF 无限表示一个空的房间。然后,我们用 231 - 1 = 2147483647 代表 INF。你可以认为通往门的距离总是小于 2147483647 的。
你要给每个空房间位上填上该房间到 最近 门的距离,如果无法到达门,则填 INF 即可。

示例:

给定二维网格:

INF  -1  0  INF
INF INF INF  -1
INF  -1 INF  -1
  0  -1 INF INF
运行完你的函数后,该网格应该变成:

  3  -1   0   1
  2   2   1  -1
  1  -1   2  -1
  0  -1   3   4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/walls-and-gates
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一种思路:

麻瓜暴力解,

问最短举例就上BFS, 从每个空房间开始BFS找最近的门。

结果超时在最后一个case。

class Solution(object):
    def wallsAndGates(self, rooms):
        """
        :type rooms: List[List[int]]
        :rtype: None Do not return anything, modify rooms in-place instead.
        """
        # 麻瓜解: 从每个空房间出发 BFS
        from collections import deque
        if not rooms or not rooms[0]:
            return rooms
        m, n = len(rooms), len(rooms[0])
        dx = [1, -1, 0, 0]
        dy = [0, 0, 1, -1]
        def bfs(x0, y0):
            step = 0
            visited = set()
            visited.add((x0, y0))
            queue = deque([((x0, y0), 0)])
            while queue:
                pos, step = queue.popleft()
                x0, y0 = pos
                if rooms[x0][y0] == 0: #找到了最近的门
                    return step
                for k in range(4):
                    x = x0 + dx[k]
                    y = y0 + dy[k]
                    if 0 <= x < m and 0 <= y < n and (x, y) not in visited and rooms[x][y] != -1:
                        visited.add((x, y))
                        queue.append(((x, y), step + 1))
            return 2147483647      
            
        for i in range(m):
            for j in range(n):
                if rooms[i][j] == 2147483647: # 从每个空房间出发
                    rooms[i][j] = bfs(i, j)
        return rooms

第二种思路:

优化一下,第一种思路是从每个空房间出发都要遍历一个整个图找最近的门,

所以会很慢,

不妨反向思考一下,从所有的门出发BFS,给遇到的所有空房间都标上距离,

BFS保证第一次标上的距离一定是最短距离,

而且这种方式只需要遍历整个图一次。

class Solution(object):
    def wallsAndGates(self, rooms):
        """
        :type rooms: List[List[int]]
        :rtype: None Do not return anything, modify rooms in-place instead.
        """
        from collections import deque
        if not rooms or not rooms[0]:
            return rooms
        m, n = len(rooms), len(rooms[0])
        dx = [1, -1, 0, 0]
        dy = [0, 0, 1, -1]
        INF = 2147483647
        queue = deque()
        def bfs(queue):
            while queue:
                pos = queue.popleft()
                x0, y0 = pos
                //print x0, y0, rooms[x0][y0]
                for k in range(4):
                    x = x0 + dx[k]
                    y = y0 + dy[k]
                    if 0 <= x < m and 0 <= y < n and rooms[x][y] == INF:
                        rooms[x][y] = rooms[x0][y0] + 1
                        queue.append((x, y))
                
        for i in range(m):
            for j in range(n):
                if rooms[i][j] == 0: #现在从每扇门出发
                    queue.append((i, j))
        bfs(queue)
        return rooms

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值