【问题标题】:Why this DFS way not working?为什么这种 DFS 方式不起作用?
【发布时间】:2017-11-06 10:04:26
【问题描述】:

问题描述:

给定一个 2D 网格,每个单元格要么是墙“W”、敌人“E”或空“0”(数字 0),返回使用一颗炸弹可以杀死的最大敌人。

由于墙壁太坚固而无法摧毁,炸弹会从种植点杀死同一行和同一列中的所有敌人,直到它撞到墙上。

请注意,您只能将炸弹放在空单元格中。

Example:
For the given grid

0 E 0 0
E 0 W E
0 E 0 0

return 3. (Placing a bomb at (1,1) kills 3 enemies)

我的 DFS 解决方案:

def maxKilledEnemies(grid):
    """
    :type grid: List[List[str]]
    :rtype: int
    """
    l_row, l_col = len(grid), len(grid[0])
    visited = [[False] * l_col for _ in range(l_row)] #using this array to avoid duplicate traverse.

    def dfs(i, j):
        if 0 <= i < l_row and 0 <= j < l_col and not visited[i][j]:
            visited[i][j] = True
            if grid[i][j] == 'W': #wall return 0
                return 0
            elif grid[i][j] == '0': #0 means we just ignore this cell and traverse it adjacents
                top_val = dfs(i - 1, j)
                down_val = dfs(i + 1, j)
                left_val = dfs(i, j - 1)
                right_val = dfs(i, j + 1)
                return left_val + right_val + top_val + down_val
            elif grid[i][j] == 'E': # Enemy and we add it by 1
                top_val = dfs(i - 1, j)
                down_val = dfs(i + 1, j)
                left_val = dfs(i, j - 1)
                right_val = dfs(i, j + 1)
                return left_val + right_val + top_val + down_val + 1
        return 0

    ret = [0]
    for i in range(l_row):
        for j in range(l_col):
            if not visited[i][j] and grid[i][j] == '0':
                val = dfs(i, j)
                ret[0] = max(val, ret[0])
    return ret[0]

Solution().maxKilledEnemies([["0","E","0","0"],["E","0","W","E"],["0","E","0","0"]]) #return 4 but expect 3.

这个想法很简单,对于每个 num 为 0 的单元格,我们遍历它 4 方向(上/下/左/右)。

我知道还有其他方法可以更智能地解决它。但我想弄清楚为什么我的方法不起作用?

【问题讨论】:

    标签: python algorithm


    【解决方案1】:

    您的代码中至少存在三个错误:

    • 在每个递归步骤中,您都会探索所有可能的方向。这使您的搜索表现得像一个洪水填充,但您只想从您正在检查的炸弹位置开始向所有方向开始。之后,沿给定方向递归(或迭代搜索)。
    • 您不检查可能的炸弹位置是否为空,因此您的代码可能会将炸弹放在敌人身上。
    • 您不会在搜索之间重置已访问的数组,以便有效地仅评估单元格 (0, 0)。

    一个解决方案是有两个功能,

    • 一个用于可能的炸弹位置。在此处检查单元格是否为空。如果是,请按北、东、南和西递归计算受害者人数。
    • 一个用于炸弹的“射线”。沿着给定的方向旅行并计算敌人,直到你撞到墙。因为光线只在一个方向传播,所以您不再需要访问过的数组。

    这并不是真正的深度优先搜索,因此您可以使用循环而不是递归调用第二个函数。

    【讨论】:

      【解决方案2】:

      可能是因为使用 DFS 不是解决方案。当您使用 DFS 时,您会搜索网格中所有可到达的空间,但对于您的问题,您应该直接搜索水平或垂直空间。 例如:在 [0][0] 使用 DFS 时,您会发现所有敌人,而不仅仅是 [0][1] 和 [1][0] 的敌人。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-11
        • 1970-01-01
        • 1970-01-01
        • 2014-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多