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.
这道题相当于一个简单的炸弹人游戏,让博主想起了小时候玩的红白机的炸弹人游戏(小霸王学习机,其乐无穷!!),放一个炸弹,然后爆炸后会炸出个‘十’字,上下左右的东西都炸掉了。这道题是个简化版,字母E代表敌人,W代表墙壁,这里说明了炸弹无法炸穿墙壁。数字0表示可以放炸弹的位置,让找出一个放炸弹的位置可以炸死最多的敌人。那么博主最开始想出的方法是建立四个累加数组 v1, v2, v3, v4,其中 v1 是水平方向从左到右的累加数组,v2 是水平方向从右到左的累加数组,v3 是竖直方向从上到下的累加数组,v4 是竖直方向从下到上的累加数组,建立好这个累加数组后,对于任意位置 (i, j),其可以炸死的最多敌人数就是 v1[i][j] + v2[i][j] + v3[i][j] + v4[i][j],最后通过比较每个位置的累加和,就可以得到结果,参见代码如下:
解法一:
class Solution {
public:
int maxKilledEnemies(vector<vector<char>>& grid) {
if (grid.empty() || grid[].empty()) return ;
int m = grid.size(), n = grid[].size(), res = ;
vector<vector<int>> v1(m, vector<int>(n, )), v2 = v1, v3 = v1, v4 = v1;
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
int t = (j == || grid[i][j] == 'W') ? : v1[i][j - ];
v1[i][j] = grid[i][j] == 'E' ? t + : t;
}
for (int j = n - ; j >= ; --j) {
int t = (j == n - || grid[i][j] == 'W') ? : v2[i][j + ];
v2[i][j] = grid[i][j] == 'E' ? t + : t;
}
}
for (int j = ; j < n; ++j) {
for (int i = ; i < m; ++i) {
int t = (i == || grid[i][j] == 'W') ? : v3[i - ][j];
v3[i][j] = grid[i][j] == 'E' ? t + : t;
}
for (int i = m - ; i >= ; --i) {
int t = (i == m - || grid[i][j] == 'W') ? : v4[i + ][j];
v4[i][j] = grid[i][j] == 'E' ? t + : t;
}
}
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
if (grid[i][j] == '') {
res = max(res, v1[i][j] + v2[i][j] + v3[i][j] + v4[i][j]);
}
}
}
return res;
}
};
在论坛里看到了史蒂芬大神提出的另一种解法,感觉挺巧妙,就搬了过来。这种解法比较省空间,写法也比较简洁,需要一个 rowCnt 变量,用来记录到下一个墙之前的敌人个数。还需要一个数组 colCnt,其中 colCnt[j] 表示第j列到下一个墙之前的敌人个数。算法思路是遍历整个数组 grid,对于一个位置 grid[i][j],对于水平方向,如果当前位置是开头一个或者前面一个是墙壁,开始从当前位置往后遍历,遍历到末尾或者墙的位置停止,计算敌人个数。对于竖直方向也是同样,如果当前位置是开头一个或者上面一个是墙壁,开始从当前位置向下遍历,遍历到末尾或者墙的位置停止,计算敌人个数。可能会有人有疑问,为啥 rowCnt 就可以用一个变量,而 colCnt 就需要用一个数组呢,为啥 colCnt 不能也用一个变量呢?原因是由遍历顺序决定的,这里是逐行遍历的,在每行的开头就统计了该行的敌人总数,所以再该行遍历没必要用数组,但是每次移动时就会换到不同的列,总不能没换个列就重新统计一遍吧,所以就在第一行时一起统计了存到数组*后来使用。有了水平方向和竖直方向敌人的个数,那么如果当前位置是0,表示可以放炸弹,更新结果 res 即可,参见代码如下:
解法二:
class Solution {
public:
int maxKilledEnemies(vector<vector<char>>& grid) {
if (grid.empty() || grid[].empty()) return ;
int m = grid.size(), n = grid[].size(), res = , rowCnt, colCnt[n];
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
if (j == || grid[i][j - ] == 'W') {
rowCnt = ;
for (int k = j; k < n && grid[i][k] != 'W'; ++k) {
rowCnt += grid[i][k] == 'E';
}
}
if (i == || grid[i - ][j] == 'W') {
colCnt[j] = ;
for (int k = i; k < m && grid[k][j] != 'W'; ++k) {
colCnt[j] += grid[k][j] == 'E';
}
}
if (grid[i][j] == '') {
res = max(res, rowCnt + colCnt[j]);
}
}
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/361
参考资料:
https://leetcode.com/problems/bomb-enemy/
https://leetcode.com/problems/bomb-enemy/discuss/83387/short-omn-time-on-space-solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Boom Enemy 炸弹人的更多相关文章
-
[LeetCode] Bomb Enemy 炸弹人
Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...
-
Leetcode: Bomb Enemy
Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...
-
Bomb Enemy 炸弹人
Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...
-
LeetCode 361. Bomb Enemy
原题链接在这里:https://leetcode.com/problems/bomb-enemy/description/ 题目: Given a 2D grid, each cell is eith ...
-
[LeetCode] 361. Bomb Enemy 炸敌人
Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...
-
Bomb Enemy -- LeetCode
Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...
-
【LeetCode】361. Bomb Enemy 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力搜索 日期 题目地址:https://leetco ...
-
leetcode 361.Bomb Enemy(lintcode 553. Bomb Enemy)
dp 分别计算从左到右.从右到左.从上到下.从下到上4个方向可能的值,然后计算所有为‘0’的地方的4个方向的值的最大值 https://www.cnblogs.com/grandyang/p/5599 ...
-
LeetCode All in One 题目讲解汇总(持续更新中...)
终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...
随机推荐
-
Flask入门1-HelloWorld
Flask是基于Python的轻量级Web开发框架,本文简述其构建web用用的基本步骤,以下内容默认开发环境为Ubuntu14.04. 本文参考Flask官方建教程翻译并整理:http://flask ...
-
51nod 1126 矩阵快速幂 水
有一个序列是这样定义的:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 给出A,B和N,求f(n)的值. Input 输 ...
-
js编码
var url = encodeURI(encodeURI("search-keyword-"+keyword+".html")); 后台uri = Strin ...
-
jQuery中each()、find()、filter()等节点操作方法
1.each(callback) 官方解释: 返回值:jQuery 概述 以每一个匹配的元素作为上下文来执行一个函数. 意味着,每次执行传递进来的函数时,函数中的this关键字都指向一个不同的DOM元 ...
-
asp.net mvc视图中嵌套分部视图
asp.net mvc中Layout相当于webForm中母版页,分部视图相当于webForm中的用户控件. 下面例子是一个视图如何嵌套分部视图: A是分部视图,B是一般视图(A,B中的代码省略) 我 ...
-
sicily 1099 Packing Passengers
/**** 题意: 求x,y 满足 x*pa+y*pb=n 同时使得 p = x*ca+y*cb的值最小,若有多种可能,则选择最大x值的组合** 分析: x*pa+y*pb=n 可以用 线性同 ...
-
c++ 13
一.向量 ... 10.size/resize/clear/capacity/reserve 1)向量的大小可增可减,使向量大小改变的函数包括:resize/push_back/pop_back/cl ...
-
javascript的stringFormat函数实现
写一个简单的stringFormat来给自己用 function stringFormat(format, args) { var formatData; if (arguments.length = ...
-
CSS总结div中的内容垂直居中的五种方法
一.行高(line-height)法 如果要垂直居中的只有一行或几个文字,那它的制作最为简单,只要让文字的行高和容器的高度相同即可,比如: p { height:30px; line-height:3 ...
-
emwin 之变量定义位置
@2018-08-13 小记 本意是想在回调函数中定义一变量暂存下拉框操作前的的设定值,与后期更改的设定值作比较后更新操作,但结果失败了 分析后,此变量定义为局部变量,emwin回调函数又是事件触发型 ...