package com.freetymekiyan.algorithms.level.medium;
/**
* 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.
* <p>
* Example:
* For the given grid
* <p>
* | 0 E 0 0
* | E 0 W E
* | 0 E 0 0
* <p>
* return 3. (Placing a bomb at (1,1) kills 3 enemies)
* <p>
* Company Tags: Google
* Tags: Dynamic Programming
*/
public class BombEnemy {
public static final char WALL = 'W';
public static final char ENEMY = 'E';
public static final char EMPTY = '0';
/**
* DP.
* Not exactly the same idea as general DP.
* Just avoid duplicate searching for number of enemies each row and each column.
* For each cell from left to right at each row:
* | Use an integer rowHits to store the # of enemies can hit at this row.
* | Only update rowHits when first column(j==0) or there is a wall at the left cell(grid[i][j-1] == 'W').
* | Use an integer array colHits[] to store the # of enemies can hit at this column.
* | Only update colHits when i == 0 or grid[i - 1][j] == 'W'.
* | If grid[i][j] is empty:
* | Update result. result = max(result, rowHits + colHits[j]).
* Return max.
*/
public int maxKilledEnemies(char[][] grid) {
if (grid == null) {
return 0;
}
int m = grid.length;
int n = m == 0 ? 0 : grid[0].length;
int max = 0;
int rowHits = 0;
int[] colHits = new int[n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == WALL) { // Note that WALL cell can be skipped.
continue;
}
if (j == 0 || grid[i][j - 1] == WALL) {
rowHits = 0;
for (int k = j; k < n && grid[i][k] != WALL; k++) {
if (grid[i][k] == ENEMY) {
rowHits++;
}
}
}
if (i == 0 || grid[i - 1][j] == WALL) {
colHits[j] = 0;
for (int k = i; k < m && grid[k][j] != WALL; k++) {
if (grid[k][j] == ENEMY) {
colHits[j]++;
}
}
}
if (grid[i][j] == EMPTY) { // Only update when the cell is empty.
max = (rowHits + colHits[j]) > max ? rowHits + colHits[j] : max;
}
}
}
return max;
}
}