Python轰炸机游戏算法复杂度优化

标签 python algorithm optimization time-complexity

我正在尝试解决以下任务:

Each cell in a 2D grid contains either a wall ('W') or an enemy ('E'), or is empty ('0'). Bombs can destroy enemies, but walls are too strong to be destroyed. A bomb placed in an empty cell destroys all enemies in the same row and column, but the destruction stops once it hits a wall.

Return the maximum number of enemies you can destroy using one bomb.

Note that your solution should have O(field.length · field[0].length) complexity because this is what you will be asked during an interview.

Example

For

field = [["0", "0", "E", "0"],
         ["W", "0", "W", "E"],
         ["0", "E", "0", "W"],
         ["0", "W", "0", "E"]]

the output should be bomber(field) = 2.

Placing a bomb at (0, 1) or at (0, 3) destroys 2 enemies.

我实现了一个简单的解决方案,但它具有 O(n^2) 复杂度(n = 宽度*高度)。我怎样才能把它变成 O(n)?该任务被标记为“贪婪”,因此可能存在一种可行的贪婪方法。 这是天真的解决方案:

def bomber(field):

    if len(field) < 1:
        return 0

    h = len(field)
    w = len(field[0])
    max_enemies = 0

    for row in range(h):
        for col in range(w):

            if field[row][col] == "0":
                cur_max = 0
                cur_row = row
                cur_col = col

                while cur_row >= 0:
                    if field[cur_row][col] == "W":
                        break
                    if field[cur_row][col] == "E":
                        cur_max += 1
                    cur_row -= 1

                cur_row = row    

                while cur_row < h:
                    if field[cur_row][col] == "W":
                        break
                    if field[cur_row][col] == "E":
                        cur_max += 1
                    cur_row += 1

                cur_row = row

                while cur_col >= 0:
                    if field[row][cur_col] == "W":
                        break
                    if field[row][cur_col] == "E":
                        cur_max += 1
                    cur_col -= 1

                cur_col = col

                while cur_col < w:
                    if field[row][cur_col] == "W":
                        break
                    if field[row][cur_col] == "E":
                        cur_max += 1
                    cur_col += 1


                if cur_max > max_enemies:
                    max_enemies = cur_max

    return max_enemies 

最佳答案

如果你考虑单行,你可以确定在线性时间内在该行的每个方格中可见多少敌人(在同一行中)。

def ranges(c):
    i = 0
    while True:
        while i < len(c) and c[i] == "W":
            i += 1
        if i == len(c):
            return
        start = i
        enemies = 0
        while i < len(c) and c[i] != "W":
            if c[i] == "E":
                enemies += 1
            i += 1
        yield range(start, i), enemies

def enemies(c):
    answer = [0] * len(c)
    for r, enemies in ranges(c):
        for i in r:
            answer[i] = enemies
    return answer

这里的 ranges 函数返回“0”或“E”的连续范围,以及每个范围内的敌人数量。然后 enemies 使用这些范围构建一个向量,该向量显示每个方格可见的敌人数量。

例如:

>>> print enemies(["0", "E", "0", "E", "W", "0", "0", "W", "E"])
[2, 2, 2, 2, 0, 0, 0, 0, 1]

使用它,我们可以为每一行和每一列构造向量,然后在 O(W*H) 时间内找到最大值。代码使用了一个技巧:zip(*grid)grid 的转置。

def best(grid):
    rows = [enemies(c) for c in grid]
    cols = [enemies(c) for c in zip(*grid)]
    return max(rows[i][j] + cols[j][i]
            for i in xrange(len(grid))
            for j in xrange(len(grid[0]))
            if grid[i][j] == '0')

并进行测试以确保其正常工作:

field = [["0", "0", "E", "0"],
         ["W", "0", "W", "E"],
         ["0", "E", "0", "W"],
         ["0", "W", "0", "E"]]

print best(field)

关于Python轰炸机游戏算法复杂度优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43265880/

相关文章:

python - Ipywidgets 在交互式而不是小部件上观察方法

python - 如何将字符串中每个单词的第一个字符大写?

c - 在 C 中为整数和字符(字符串)数组中的最小元素编写通用函数

algorithm - 如何用graphx求和边缘权重

php - MySQL & PHP 交叉加密/解密算法?

sql - 需要使用 JOIN 优化 SQL 查询的技巧

string - 一系列字符串的最长公共(public)子序列

python - 在混合了 int 和 string python 的数据帧上使用 groupby.sum()

Python Gae 应用程序部署后不发送电子邮件

c# - 正确的线程方法