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)

Credits:
Special thanks to @memoryless for adding this problem and creating all test cases.

方法一:

遍历数组中的每一个点,当前点能够得到的最大值为从左边的头(边界或wall)到右边的头(遇到边界或wall)的值(row值)+从上面的头(边界或wall)到下面的头(遇到边界或wall)的值(col值)。每一个row范围内的点都共用当前的row值,每一个col范围内的点都共用当前col值。当从新的边界或者wall开始时,相当于进入了新的一段范围,要重新计算row值或者col值。
1.遍历数组中每一个点,若为0则开始计算
2.若当前点为第一列或者左边一个点为wall,表明进入了一个新的区间,需要重新计算。从该点开始一直向右直到遇到边界或者wall,在该过程中,每遇到一个E就将row值+1+

3.若当前点为第一行或者上边一个点为wall,表明进入了一个新的区间,需要重新计算。从该点开始一直向下直到遇到边界或者wall,在该过程中,每遇到一个E就将col值+1
4.重复2-3步骤

方法二:

上面的方法,会存在大量的重复计算。好的解法是用DP,用一个cache来存下部分结果来避免重复运算。这里用一个m*2的数组enemyCount来储存每一行的结果。enemyCount[i][0]储存了第i行某一个W的位置,enemyCount[i][1]储存了enemyCount[i][0]所标识的W到之前一个W之间E的个数,初始化:enemyCount[i][0] = -1,enemyCount[i][1] = 0。

Java: Iteration

public class Solution {
/**
* @param grid Given a 2D grid, each cell is either 'W', 'E' or '0'
* @return an integer, the maximum enemies you can kill using one bomb
*/
public int maxKilledEnemies(char[][] grid) {
if(grid == null || grid.length == 0 || grid[0].length == 0){
return 0;
} int m = grid.length;
int n = grid[0].length; int result = 0;
int rows = 0;
int[] cols = new int[n];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (j == 0 || grid[i][j-1] == 'W') {
rows = 0;
for (int k = j; k < n && grid[i][k] != 'W'; ++k)
if (grid[i][k] == 'E')
rows += 1;
}
if (i == 0 || grid[i-1][j] == 'W') {
cols[j] = 0;
for (int k = i; k < m && grid[k][j] != 'W'; ++k)
if (grid[k][j] == 'E')
cols[j] += 1;
} if (grid[i][j] == '0' && rows + cols[j] > result)
result = rows + cols[j];
}
}
return result;
}
}

Java: Iteration

public class Solution {
public int maxKilledEnemies(char[][] A) {
if (A == null || A.length == 0 || A[0].length == 0) {
return 0;
} int m = A.length;
int n = A[0].length;
int[][] up = new int[m][n];
int[][] down = new int[m][n];
int[][] left = new int[m][n];
int[][] right = new int[m][n];
int i, j, t; for (i = 0; i < m; ++i) {
for (j = 0; j < n; ++j) {
up[i][j] = 0;
if (A[i][j] != 'W') {
if (A[i][j] == 'E') {
up[i][j] = 1;
} if (i - 1 >= 0) {
up[i][j] += up[i-1][j];
}
}
}
} for (i = m - 1; i >= 0; --i) {
for (j = 0; j < n; ++j) {
down[i][j] = 0;
if (A[i][j] != 'W') {
if (A[i][j] == 'E') {
down[i][j] = 1;
} if (i + 1 < m) {
down[i][j] += down[i+1][j];
}
}
}
} for (i = 0; i < m; ++i) {
for (j = 0; j < n; ++j) {
left[i][j] = 0;
if (A[i][j] != 'W') {
if (A[i][j] == 'E') {
left[i][j] = 1;
} if (j - 1 >= 0) {
left[i][j] += left[i][j-1];
}
}
}
} for (i = 0; i < m; ++i) {
for (j = n - 1; j >= 0; --j) {
right[i][j] = 0;
if (A[i][j] != 'W') {
if (A[i][j] == 'E') {
right[i][j] = 1;
} if (j + 1 < n) {
right[i][j] += right[i][j+1];
}
}
}
} int res = 0;
for (i = 0; i < m; ++i) {
for (j = 0; j < n; ++j) {
if (A[i][j] == '0') {
t = up[i][j] + down[i][j] + left[i][j] + right[i][j];
if (t > res) {
res = t;
}
}
}
} return res;
}
}

Java: DP

public class Solution {
public int maxKilledEnemies(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
} int[][] enemyCount = new int[grid.length][2];
for (int i = 0; i < enemyCount.length; i++) {
enemyCount[i][0] = -1;
} int max = 0;
for (int j = 0; j < grid[0].length; j++) {
int colEnemy = countColEnemy(grid, j, 0);
for (int i = 0; i < grid.length; i++) {
if (grid[i][j] == '0') {
if (j > enemyCount[i][0]) {
update(enemyCount, grid, i, j);
}
max = Math.max(colEnemy + enemyCount[i][1], max);
}
if (grid[i][j] == 'W') {
colEnemy = countColEnemy(grid, j, i + 1);
}
}
}
return max;
} private void update(int[][] enemyCount, char[][] grid, int i, int j) {
int count = 0;
int k = enemyCount[i][0] + 1;
while (k < grid[0].length && (grid[i][k] != 'W' || k < j)) {
if (grid[i][k] == 'E') {
count += 1;
}
if (grid[i][k] == 'W') {
count = 0;
}
k += 1;
}
enemyCount[i][0] = k;
enemyCount[i][1] = count;
} private int countColEnemy(char[][] grid, int j, int start) {
int count = 0;
int i = start;
while (i < grid.length && grid[i][j] != 'W') {
if (grid[i][j] == 'E') {
count += 1;
}
i += 1;
}
return count;
}
}

Python:

class Solution(object):
def maxKilledEnemies(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
result = 0
if not grid or not grid[0]:
return result down = [[0 for _ in xrange(len(grid[0]))] for _ in xrange(len(grid))]
right = [[0 for _ in xrange(len(grid[0]))] for _ in xrange(len(grid))]
for i in reversed(xrange(len(grid))):
for j in reversed(xrange(len(grid[0]))):
if grid[i][j] != 'W':
if i + 1 < len(grid):
down[i][j] = down[i + 1][j]
if j + 1 < len(grid[0]):
right[i][j] = right[i][j + 1]
if grid[i][j] == 'E':
down[i][j] += 1
right[i][j] += 1 up = [0 for _ in xrange(len(grid[0]))]
for i in xrange(len(grid)):
left = 0
for j in xrange(len(grid[0])):
if grid[i][j] == 'W':
up[j], left = 0, 0
elif grid[i][j] == 'E':
up[j] += 1
left += 1
else:
result = max(result,
left + up[j] + right[i][j] + down[i][j]) return result

C++:

// Time:  O(m * n)
// Space: O(m * n) class Solution {
public:
int maxKilledEnemies(vector<vector<char>>& grid) {
int result = 0;
if (grid.empty() || grid[0].empty()) {
return result;
} vector<vector<int>> down{grid.size(), vector<int>(grid[0].size())};
vector<vector<int>> right{grid.size(), vector<int>(grid[0].size())};
for (int i = grid.size() - 1; i >= 0; --i) {
for (int j = grid[0].size() - 1; j >= 0; --j) {
if (grid[i][j] != 'W') {
if (i + 1 < grid.size()) {
down[i][j] = down[i + 1][j];
}
if (j + 1 < grid[0].size()) {
right[i][j] = right[i][j + 1];
}
if (grid[i][j] == 'E') {
++down[i][j];
++right[i][j];
}
}
}
} int left = 0;
vector<int> up(grid[0].size());
for (int i = 0; i < grid.size(); ++i) {
left = 0;
for (int j = 0; j < grid[0].size(); ++j) {
if (grid[i][j] == 'W') {
up[j] = 0;
left = 0;
} else if (grid[i][j] == 'E') {
++up[j];
++left;
} else {
result = max(result, left + up[j] + right[i][j] + down[i][j]);
}
}
} return result;
}
};

C++:

class Solution {
public:
int maxKilledEnemies(vector<vector<char>>& grid) {
if (grid.empty() || grid[0].empty()) return 0;
int m = grid.size(), n = grid[0].size(), res = 0;
vector<vector<int>> v1(m, vector<int>(n, 0)), v2 = v1, v3 = v1, v4 = v1;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
int t = (j == 0 || grid[i][j] == 'W') ? 0 : v1[i][j - 1];
v1[i][j] = grid[i][j] == 'E' ? t + 1 : t;
}
for (int j = n - 1; j >= 0; --j) {
int t = (j == n - 1 || grid[i][j] == 'W') ? 0 : v2[i][j + 1];
v2[i][j] = grid[i][j] == 'E' ? t + 1 : t;
}
}
for (int j = 0; j < n; ++j) {
for (int i = 0; i < m; ++i) {
int t = (i == 0 || grid[i][j] == 'W') ? 0 : v3[i - 1][j];
v3[i][j] = grid[i][j] == 'E' ? t + 1 : t;
}
for (int i = m - 1; i >= 0; --i) {
int t = (i == m - 1 || grid[i][j] == 'W') ? 0 : v4[i + 1][j];
v4[i][j] = grid[i][j] == 'E' ? t + 1 : t;
}
}
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == '0') {
res = max(res, v1[i][j] + v2[i][j] + v3[i][j] + v4[i][j]);
}
}
}
return res;
}
};

C++:  

class Solution {
public:
int maxKilledEnemies(vector<vector<char>>& grid) {
if (grid.empty() || grid[0].empty()) return 0;
int m = grid.size(), n = grid[0].size(), res = 0, rowCnt, colCnt[n];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (j == 0 || grid[i][j - 1] == 'W') {
rowCnt = 0;
for (int k = j; k < n && grid[i][k] != 'W'; ++k) {
rowCnt += grid[i][k] == 'E';
}
}
if (i == 0 || grid[i - 1][j] == 'W') {
colCnt[j] = 0;
for (int k = i; k < m && grid[k][j] != 'W'; ++k) {
colCnt[j] += grid[k][j] == 'E';
}
}
if (grid[i][j] == '0') {
res = max(res, rowCnt + colCnt[j]);
}
}
}
return res;
}
};

  

  

All LeetCode Questions List 题目汇总

  

[LeetCode] 361. Bomb Enemy 炸敌人的更多相关文章

  1. LeetCode 361. Bomb Enemy

    原题链接在这里:https://leetcode.com/problems/bomb-enemy/description/ 题目: Given a 2D grid, each cell is eith ...

  2. leetcode 361.Bomb Enemy(lintcode 553. Bomb Enemy)

    dp 分别计算从左到右.从右到左.从上到下.从下到上4个方向可能的值,然后计算所有为‘0’的地方的4个方向的值的最大值 https://www.cnblogs.com/grandyang/p/5599 ...

  3. 【LeetCode】361. Bomb Enemy 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力搜索 日期 题目地址:https://leetco ...

  4. 361. Bomb Enemy

    这个题确实不会..只能想到naive的做法,不过那样应该是O(n³),不会满足要求. 看TAG是DP,那应该是建立DP[][]记录每点可炸的情况.一个点如果左边/上边是墙,或者左边/上边是边界,就要重 ...

  5. [LeetCode] Bomb Enemy 炸弹人

    Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...

  6. Bomb Enemy -- LeetCode

    Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...

  7. Leetcode: Bomb Enemy

    Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...

  8. Bomb Enemy

    Description Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number z ...

  9. Bomb Enemy 炸弹人

    Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...

随机推荐

  1. Error while obtaining UI hierarchy XML file: com.android.ddmlib.SyncException: Remote object doesn't

    在使用真机定位页面元素时启动uiautomatorviewer.bat ,报错Error while obtaining UI hierarchy XML file: com.android.ddml ...

  2. 查询响应慢,DB近乎崩溃

    时间:18.11.22 一. 起由: 公司最近因业务,有大量注册,每天大约几万,貌似也不太高? 晚上8点左右,网站后台,前台突然大面积提示502.网站几乎瘫痪.买的阿里云的负载均衡和读写分离.分别是5 ...

  3. Hibernate缓存简介和对比、一级缓存、二级缓存详解

    一.hibernate缓存简介 缓存的范围分为3类:  1.事务范围(单Session即一级缓存)     事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象 ...

  4. CentOS 6.x 无法格式化大于16TB的ext4分区处理

    CentOS 6.x 在格式化大于16TB的ext4分区时,会提示如下错误: mke2fs 1.41.12 (17-May-2010) mkfs.ext4: Size of device /dev/s ...

  5. php curl模拟post请求的例子

    curl 在php中要模拟post请求数据提交我们会使用到curl函数,下面我来给大家举几个curl模拟post请求提交数据例子有需要的朋友可参考参考. 注意:curl函数在php中默认是不被支持的, ...

  6. 自定义注解-aop实现日志记录

    关于注解,平时接触的可不少,像是 @Controller.@Service.@Autowried 等等,不知道你是否有过这种疑惑,使用 @Service 注解的类成为我们的业务类,使用 @Contro ...

  7. Chocolatey 方便的windows 包管理工具

    windows 在包管理上一般大家都是网上下载二进制文件或者就是通过软件管家进行安装,这些对于开发人员可能就有点不是 很专业了, Chocolatey 是一个不错的windows 软件包管理工具 安装 ...

  8. SVN 常用 下载仓库

    仓库的基本使用: 1.管理仓库的人会给你一个SVN的仓库地址,如: https://192.168.2.98:8443/svn/建筑工程健康监测系统 2.然后就下载仓库里面的所有文件 3.对仓库做增删 ...

  9. Codevs 2800 送外卖(状压DP)

    2800 送外卖 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n ...

  10. 1、zookeeper入门

    一.什么是Zookeeper Zookeeper是Google的Chubby一个开源的实现,是一个开源的,为分布式提供协调服务的Apache项目; 它包含一个简单的原语集,分布式应用程序可以基于它实现 ...