Description:
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)
Link:
https://leetcode.com/problems/bomb-enemy/description/
解题方法:
这道题的暴力破解就是在每个点算出其横行和纵行的敌人数,但是这样会有很多重复运算,所以可以用DP来减少重复运算。
比如我们用DP1[i][j]来表示在坐标(i, j)的横行敌人数,用DP2[i][j]来表示纵行敌人数。
那么当grid[i][j - 1]位置不是墙的时候,DP1[i][j] = DP1[i][j - 1],否则我们从左往右算这一行的敌人数,直到碰墙。
同理当grid[i - 1][j]位置不是墙的时候,DP2[i][j] = DP2[i - 1][j], 否则我们从上往下算这一列的地人数,直到碰墙。
所以我们遍历grid的每个点,都进行上面的运算,就可以得到在该点放炸弹能炸死的敌人数。
Time Complexity:
O(mn)时间,因为每个节点最多会被走到2次(一次是遍历到该节点,一次是算敌人数的时候,算过一次的节点其实不会再被算第二次)
完整代码:
int maxKilledEnemies(vector<vector<char>>& grid) {
int row = grid.size();
if(!row)
return 0;
int col = grid[0].size();
if(!col)
return 0;
vector<vector<pair<int, int>>> DP(row, vector<pair<int, int>>(col, pair<int,int>(0, 0)));
int result = 0;
for(int i = 0; i < row; i++) {
for(int j = 0; j < col; j++) {
if(grid[i][j] == 'W')
continue;
//count enemies at the same row
if(j == 0 || grid[i][j - 1] == 'W') {
int cnt = 0;
for(int k = j; k < col; k++) {
if(grid[i][k] == 'W')
break;
else if(grid[i][k] == 'E')
cnt++;
}
DP[i][j].first = cnt;
}
else
DP[i][j].first = DP[i][j - 1].first;
//count enemies at the same col
if(i == 0 || grid[i - 1][j] == 'W') {
int cnt = 0;
for(int k = i; k < row; k++) {
if(grid[k][j] == 'W')
break;
else if(grid[k][j] == 'E')
cnt++;
}
DP[i][j].second = cnt;
}
else
DP[i][j].second = DP[i - 1][j].second;
int curr = DP[i][j].first + DP[i][j].second;
if(grid[i][j] == 'E')
continue;
result = curr > result ? curr : result;
}
}
return result;
}