这个DFS解决方案有什么问题?

时间:2017-11-08 15:55:41

标签: python algorithm

问题描述:

你想在空旷的土地上建造一座房子,以最短的距离到达所有建筑物。您只能向上,向下,向左和向右移动。您将获得值为0,1或2的2D网格,其中:

每个0都标志着一片空地,你可以自由地经过。 每1个标记一个您无法通过的建筑物。 每个2都标志着你无法通过的障碍。 例如,给定(0,0),(0,4),(2,2)处的三个建筑物和(0,2)处的障碍物:

1 - 0 - 2 - 0 - 1
|   |   |   |   |
0 - 0 - 0 - 0 - 0
|   |   |   |   |
0 - 0 - 1 - 0 - 0

点(1,2)是建造房屋的理想空地,因为3 + 3 + 1 = 7的总行程距离是最小的。所以返回7。

我用BFS方式解决了这个问题。然后我想用DFS方式解决它,但卡住了。以下是我的代码:

class Solution(object):
    def shortestDistance(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        rl, cl = len(grid), len(grid[0])
        builds = sum([col for row in grid for col in row if col == 1])
        dist, hit = [[0] * cl for _ in range(rl)], [[0] * cl for _ in range(rl)]

        def dfs(x, y, step):
            '''
            Wrong answer, it seems result dist alway keep the longest distance?
            '''
            if 0 <= x < rl and 0 <= y < cl and not visited[x][y]:
                visited[x][y] = True
                if grid[x][y] == 0:
                    dist[x][y] += (step + 1)
                    hit[x][y] += 1

                    dfs(x - 1, y, step + 1)
                    dfs(x + 1, y, step + 1)
                    dfs(x, y - 1, step + 1)
                    dfs(x, y + 1, step + 1)

        def bfs(x, y):
            '''
            works properly
            '''
            visited = [[False] * cl for _ in range(rl)]
            queue =[(x, y, 0)]
            while queue:
                k, m, step = queue.pop(0)
                for i, j in ((k - 1, m), (k + 1, m), (k, m - 1), (k, m + 1)):
                    if 0 <= i < rl and 0 <= j < cl and not visited[i][j]:
                        visited[i][j] = True
                        if grid[i][j] == 0:
                            dist[i][j] += (step + 1)
                            hit[i][j] += 1

                            queue.append((i, j, step + 1))
        for i in range(rl):
            for j in range(cl):
                if grid[i][j] == 1:
                    # bfs(i, j) # this works properly
                    visited = [[False] * cl for _ in range(rl)]
                    dfs(i - 1, j, 0)
                    dfs(i + 1, j, 0)
                    dfs(i, j - 1, 0)
                    dfs(i, j + 1, 0)

        ret = float('inf')
        for i in range(rl):
            for j in range(cl):
                if grid[i][j] == 0 and hit[i][j] == builds:
                    ret = min(ret, dist[i][j])
        return ret if ret != float('inf') else -1

# expect 7
print Solution().shortestDistance([[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]])

这是一种典型的图搜索问题。通常可以用DFS和BFS方式解决。只是无法弄清楚如何以DFS方式修复它?

1 个答案:

答案 0 :(得分:0)

简单DFS并非旨在找到最短路径。通过一些回溯和谨慎的标记以及对被访问节点的取消标记,您可以使用它来查找到达给定点的所有路径并选择最短路径,但它不必要地复杂且比BFS慢。