【LeetCode - 361】轰炸敌人

1、题目描述

在这里插入图片描述

2、解题思路

  如果直接暴力,可以对每一个空格都计算往左往右往上往下能直接接触的敌人的数量。

  在暴力统计的基础上,重复利用已经计算的结果。

  比如,如果我已经计算好一个格子的左右能直接接触的敌人,如果它往右一步的格子也是空格,那么,按道理来说,这个空格的左侧敌人数量是一样的,我们得重复利用这个信息。

  定义一个 dp[][] ,其中 dp[i][j] 表示 (i,j) 格子上下左右能直接接触到的敌人的数量。

  对于一个空格 (i, j) 来说,我们需要从左到右统计才能直到它左侧有多少个敌人,从右到左统计才直到它右侧有多少个敌人。

  因此算法总共有四次非嵌套的遍历,左右、右左、上下、下上。

  最后遍历一次所有空格,找到 dp[i][j] 值最大的即可。

  算法虽然有多次遍历,但都不是嵌套的,所以时间复杂度还是 O(mn)

3、解题代码

class Solution {
    public int maxKilledEnemies(char[][] grid) {
        int rows = grid.length;
        if (rows == 0) return 0;
        int cols = grid[0].length;
        if (cols == 0) return 0;
        int ans = 0;
        int[][] dp = new int[rows][cols];
        int pre = 0;    // 敌人的个数
        // 遍历每一行
        for (int i = 0; i < rows; i++) {
            pre = 0;
            // 从左到右
            for (int j = 0; j < cols; j++) {
                if (grid[i][j] == 'W') {
                    pre = 0;   // 当前格子是墙,前一个格子不能在这边接触到任何敌人
                } else if (grid[i][j] == 'E') {
                    pre++;    // 当前格子就是敌人,告诉前一个能接触的敌人加一
                } else { // '0'
                    dp[i][j] += pre;   // 当前格子是空格,它能接触到的敌人就是 pre
                }
            }
            pre = 0;
            // 从右到左
            for (int j = cols - 1; j >= 0; j--) {
                if (grid[i][j] == 'W') {
                    pre = 0;    // 当前格子是墙,往右不能接触到任何敌人
                } else if (grid[i][j] == 'E') {
                    pre++;
                } else {
                    dp[i][j] += pre;
                }
            }
        }
        // 遍历每一列
        for (int j = 0; j < cols; j++) {
            pre = 0;
            // 从上到下
            for (int i = 0; i < rows; i++) {
                if (grid[i][j] == 'W') {
                    pre = 0;
                } else if (grid[i][j] == 'E') {
                    pre++;
                } else {
                    dp[i][j] += pre;
                }
            }
            pre = 0;
            // 从下到上
            for (int i = rows - 1; i >= 0; i--) {
                if (grid[i][j] == 'W') {
                    pre = 0;
                } else if (grid[i][j] == 'E') {
                    pre++;
                } else {
                    dp[i][j] += pre;
                }
            }
        }
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (grid[i][j] == '0') {
                    ans = Math.max(ans, dp[i][j]);
                }
            }
        }
        return ans;
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值