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. 基于springboot2.x集成缓存注解及设置过期时间

    添加以下配置信息: /** * 基于注解添加缓存 */ @Configuration @EnableCaching public class CacheConfig extends CachingCo ...

  2. C#将文件转成16进制码流写入数据库存起来,访问的时候再还原成PDF文件。

    转自https://blog.csdn.net/liubowei_0312/article/details/53378146 适合将文件写入数据库,远程访问的时候还原1.首先把文件转成十六进制文件流 ...

  3. Python开发应用-正则表达进行排序搜索

    re模块提供了3个方法对输入的字符串进行确切的查询,match和search最多只会返回一个匹配条件的子串,可以理解为非贪婪模式,而findall会返回N个匹配条件的子串,可以理解为贪婪模式 re.m ...

  4. 2019-2020-1 20199301《Linux内核原理与分析》第八周作业

    第七章 可执行程序工作原理 ELF概述: 目标平台:它决定了编译器使用的机器命令集. ABI(目标文件) 目标文件和目标平台是二进制兼容的,即该目标文件已经是适应某一种CPU体系结构的二进制指令. E ...

  5. SparkSQL读写外部数据源-jext文件和table数据源的读写

    object ParquetFileTest { def main(args: Array[String]): Unit = { val spark = SparkSession .builder() ...

  6. [PWA] Storage information for PWA application

    Be careful with the storage use cases, free the storage when it is necessary.

  7. asp.net Web 项目的文件/文件夹上传下载

    以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  ...

  8. Java Web 项目的文件/文件夹上传下载

    需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验: 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包 ...

  9. 26-ESP8266 SDK开发基础入门篇--编写WIFI模块 SmartConfig/Airkiss 一键配网

    https://www.cnblogs.com/yangfengwu/p/11427504.html SmartConfig/Airkiss 配网需要APP/微信公众号,这节大家先使用我做好的APP/ ...

  10. 前端微信小程序电影类仿淘票票微信小程序

    需求描述及交互分析设计思路和相关知识点电影界面顶部页签切换效果设计正在热映界面布局设计即将上映界面布局设计电影详情页设计我的界面列表导航设计登录设计 相关知识点(1)swiper滑块视图容器组件,可以 ...