[leetcode][361]bomb enemy

Problem

Given a 2D grid, each cell is either a wall ‘W’, an enemy ‘E’ or empty ‘0’ (the number zero), return the maximum enemies you can kill using one bomb. The bomb kills all the enemies in the same row and column from the planted point until it hits the wall since the wall is too strong to be destroyed. Note that you can only put the bomb at an empty cell.

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)

Solution

这是一个十字形爆炸的题目,即在矩阵中的某一点 (i, j) 爆炸,则以该点为中心向第i行和第j列产生爆炸,直到遇到墙‘W’则该行或该列的爆炸终止,计算放在哪一点(可放炸弹点初始值为‘0’),可以爆炸波及的敌人‘E’最多。最朴素的方法即遍历矩阵每一个‘0’点,计算该点分别向上下左右四个方向直至遇到墙可以达到的敌人数,将4个值相加得到每个点的数量从而得到最大的值。设该矩阵为m × n, 则该方法的时间复杂度是O(m × n × (m + n))。值得注意的是,对同一行介于两堵墙之间的任意点,在行方向上可以达到的敌人数是一样的(列也类似),因此我们可以简化计算,对这样的点用一个 rowCnt 变量存储,再分别计算每个点列方向上的敌人数。在最极端的情况下,如果任意一行的‘0’点之间都不存在‘W’,计算复杂度降到
O(m × n × (1 + n))。显然,可以根据行列数的大小决定用 rowCnt 或是 colCnt.

public int maxKilledEnemies(char[][] grid) {
        if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0)
            return 0;
        int rows = grid.length;
        int cols = grid[0].length;
        int res = 0;
        int rowCnt = 0;
        int[] colCnt = new int[cols];
        for (int i = 0; i < rows; i ++) {
            for (int j = 0; j < cols; j++) {
                if (j == 0 || grid[i][j - 1] == 'W') {
                    rowCnt = 0;
                    for (int k = j; k < cols && grid[i][k] != 'W'; k++) {
                        if (grid[i][k] == 'E')
                            rowCnt ++;
                    }
                }
                if (i == 0 || grid[i - 1][j] == 'W') {
                    colCnt[j] = 0;
                    for (int k = i; k < rows && grid[k][j] != 'W'; k++) {
                        if (grid[k][j] == 'E')
                            colCnt[j] ++;
                    }
                }
                if (grid[i][j] == '0')
                    res = Math.max(res, rowCnt + colCnt[j]);
            }
        }
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值