zoukankan      html  css  js  c++  java
  • Walls and Gates

    You are given a m x n 2D grid initialized with these three possible values.

    1. -1 - A wall or an obstacle.
    2. 0 - A gate.
    3. INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than 2147483647.

    Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF.

    For example, given the 2D grid:

    INF  -1  0  INF
    INF INF INF  -1
    INF  -1 INF  -1
      0  -1 INF INF

    After running your function, the 2D grid should be:

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

    这题比较有意思,要求算出空房间到门的最近距离。

    直觉BFS,之前看到谷歌面经求二维矩阵上的最短距离,这题类似。一个比较naive的做法是,先找出所有门,然后对每个门做BFS,二维矩阵上的DFS和BFS一般需要使用hashset或者visited矩阵来判断是否已经遍历过。但是这题在计算距离时可以根据距离的大小判断是否重复遍历。已经在一次BFS里遍历过了,再到这里的距离肯定大于之前的距离。 所以不做更新。代码如下:

    class Solution(object):
        def wallsAndGates(self, rooms):
            """
            :type rooms: List[List[int]]
            :rtype: void Do not return anything, modify rooms in-place instead.
            """
            if not rooms:
                return
            m = len(rooms)
            n = len(rooms[0])
            queue = collections.deque()
            walls = []
            for i in xrange(m):
                for j in xrange(n):
                    if rooms[i][j] == 0:
                        walls.append((i,j))
            dx = [1, 0, -1, 0]
            dy = [0, -1, 0, 1]
            for wall in walls:
                queue.append(wall)
                while queue:
                    cur = queue.popleft()
                    for j in xrange(4):
                        x = dx[j] + cur[0]
                        y = dy[j] + cur[1] #rooms[cur[0]][cur[1]] < rooms[x][y] - 1判断是否在此次BFS重复遍历,或早是否此次BFS得不到最短距离。
                    if x >= 0 and x < m and y >= 0 and y < n and rooms[x][y] > 0 and rooms[cur[0]][cur[1]] < rooms[x][y] - 1 :
      rooms[x][y]
    = rooms[cur[0]][cur[1]] + 1
      queue.append((x,y))
    return

    这种做法其实有很大的冗余存在,我们完全可以利用BFS的性质,做一个有多个起点的BFS。也就是多个门开始放在一个queue里。利用BFS的性质,第一个处理到空房间的,肯定是最短距离,代码如下:

    class Solution(object):
        def wallsAndGates(self, rooms):
            """
            :type rooms: List[List[int]]
            :rtype: void Do not return anything, modify rooms in-place instead.
            """
            if not rooms:
                return
            m = len(rooms)
            n = len(rooms[0])
            queue = collections.deque()
            walls = []
            for i in xrange(m):
                for j in xrange(n):
                    if rooms[i][j] == 0:
                        queue.append((i,j))
            dif = [0, 1, 0, -1, 0]
            INT_MAX = 2**31 - 1
       
            while queue:
                cur = queue.popleft()
                for j in xrange(4):
                    x = dif[j] + cur[0]
                    y = dif[j+1] + cur[1]
                    if 0 <= x < m and  0 <= y < n and rooms[x][y] > 0 and rooms[x][y] == INT_MAX : #第一次处理
                        rooms[x][y] = rooms[cur[0]][cur[1]] + 1
                        queue.append((x,y))
            return 

    第一种解法平均复杂度为O(k*n^2),k为门的数目,最差时间复杂度为O(n^4)。而第二种解法的平均和最差复杂度都是O(n^2)

    具体见这个帖子:

    https://discuss.leetcode.com/category/358/walls-and-gates

  • 相关阅读:
    java编程继承的第一原则
    Java基本语法总结
    java 语言实现的随机数生成算法
    java实现微公众平台自定义菜单
    使用Java调用谷歌搜索
    Java 语言实现的随机数生成算法
    浅谈Java中的instanceof关键字
    Java 编程基础 类和继承总结
    异常封装提高Java代码质量
    CSS-font
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5678703.html
Copyright © 2011-2022 走看看