- Bomb Enemy
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.
Example
Example1
Input:
grid =[
“0E00”,
“E0WE”,
“0E00”
]
Output: 3
Explanation:
Placing a bomb at (1,1) kills 3 enemies
Example2
Input:
grid =[
“0E00”,
“EEWE”,
“0E00”
]
Output: 2
Explanation:
Placing a bomb at (0,0) or (0,3) or (2,0) or (2,3) kills 2 enemies
Notice
You can only put the bomb at an empty cell.
解法1:
参考自网上。时间复杂度O(n^3)。
对每个i,j, 如果i==0,或上面一个元素为W,则计算j列从当前行到nRow累计的Enemy数。
如下图所示,当i=0,j=1时,所计算的累计enemy数为2(因为列1有2个E)。但grid[0][1]不为0,所以将colCount[1]保存下来,当i=1,j=1的时候就可以用上了。注意这里如果不保留下来colCount[j],仅仅用一个colEnemy的话,对固定的i,每个j都会重新计算colEnemy,那样就会不准了,即i=0,j=1算好的colEnemy的值会被i=0,j=2计算的colEnemy替代。
而rowEnemy因为j本来就是从大到小迭代过来的,所以用一个rowEnemy就足够了。
[0 E 0 0]
[E 0 W E]
[0 E 0 0]
代码如下:
class Solution {
public:
/**
* @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
*/
int maxKilledEnemies(vector<vector<char>> &grid) {
int nRow = grid.size();
if (nRow == 0) return 0;
int nCol = grid[0].size();
int rowEnemies = 0;
vector<int> colCounts(nCol, 0);
// int colEnemies = 0;
int maxCount = 0;
for (int i = 0; i < nRow; ++i) {
for (int j = 0; j < nCol; ++j) {
if (i == 0 || grid[i - 1][j] == 'W') {
colCounts[j] = 0;
colEnemies = 0;
for (int k = i; k < nRow && grid[k][j] != 'W'; ++k) {
if (grid[k][j] == 'E') {
colCounts[j]++;
// colEnemies++;
}
}
}
if (j == 0 || grid[i][j - 1] == 'W') {
rowEnemies = 0;
for (int k = j; k < nCol && grid[i][k] != 'W'; ++k) {
if (grid[i][k] == 'E') rowEnemies++;
}
}
if (grid[i][j] == '0') {
maxCount = max(maxCount, rowEnemies + colCounts[j]);
// maxCount = max(maxCount, rowEnemies + colEnemies);
}
}
}
return maxCount;
}
};
解法2:也是参考自网上。感觉非常牛。
从上下左右四个方向累加。复杂度只有O(n^2)。
代码如下:
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) { //up->down
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) { //down->up
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) { //left->right
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) { //right->left
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;
}
解法3:
这题应该也可以用DFS做,对每个0,上下左右4个DFS,直到遇到W。或者不用DFS,直接往4个方向搜也可。
但时间复杂度高。下次做。
本文探讨了在二维网格中,使用一枚炸弹消灭最多敌军的算法策略。提供了三种解法,包括时间复杂度O(n^3)的逐行逐列计算、O(n^2)的四方向累加优化方案,以及待实现的深度优先搜索方法。
249

被折叠的 条评论
为什么被折叠?



