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)
思路:
1. 这道题直接粗暴的方法是:对每一个为0的位置做整行、整列的扫描,计算对应的Enemy个数,然后求所有个数中最大值。这样复杂度就很高。原因是做了大量重复的工作,例如:上文例子中a[0][0]=0,需要对第0行搜索,然后a[0][2]=0,仍需要对第0行搜索,这就是重复工作。遇到这样的情况,一般情况下就是把以及搜索过的位置记录下来,每次搜索前查询是否已经搜索过了。
2. 我想的方法:新建一个同样尺寸2D的array存放每一个位置的这一行(可能被W隔开)的E个数,第一遍扫描后,第二遍扫描则一列一列的扫描,把每列的E也计算相加,求最大值!这个方法看起来简单,但是比较费空间。
//方法1:
int maxKilledEnemies(vector<vector<char>>& grid) {
//
if(grid.empty()) return 0;
int m=grid.size();
int n=grid[0].size();
vector<vector<int>> counts(m,vector<int>(n));
for(int i=0;i<m;i++){
int rowCnt=0;
for(int j=0;j<n;j++){
if(grid[i][j]!='0') continue;
if(j==0||grid[i][j-1]=='W'){
rowCnt=0;
for(int k=j+1;k<n;k++){
if(grid[i][k]=='W') break;
if(grid[i][k]=='E')
rowCnt++;
}
}
counts[i][j]=rowCnt;
}
}
int res=0;
for(int j=0;j<n;j++){
int colCnt=0;
for(int i=0;i<m;i++){
if(grid[i][j]!='0') continue;
if(i==0||grid[i-1][j]=='W'){
colCnt=0;
for(int k=i+1;k<m;k++){
if(grid[k][j]=='W') break;
if(grid[k][j]=='E')
colCnt++;
}
}
counts[i][j]+=colCnt;
res=max(res,counts[i][j]);
}
}
return res;
}
- 仔细分析方法1,先计算所有位置对应行的敌人数,然后存起来,再计算所有位置对应列的敌人数,在加起来。这个方法简单就在于先计算完一个参数,再计算另一个参数。注意到,这样做比较浪费空间,因为有很多数是一样的!可以不用等第一个参数计算完存好了再计算第二个,可以第一个参数计算好后,修改之前即计算第二个参数,这样交叉的形式计算!
2.具体作法,参考了http://www.cnblogs.com/grandyang/p/5599289.html 解法2. 每一行的值为0的地方看前面是否是W或者边界,如果是,则计算rowCnt;否则rowCnt肯定以及计算过,可以直接使用,不用重新计算;在每个位置还需要计算colCnt,类似的,如果这个位置的上面是边界或W,则从上往下计算E的个数,然后和rowCnt相加更新最大的敌人数;否则就直接使用colCnt,因此需要建一个array来存每一列对应的colCnt.
int maxKilledEnemies(vector<vector<char>>& grid) {
//
if(grid.empty()) return 0;
int m=grid.size();
int n=grid[0].size();
vector<int> colCnt(n,0);
int res=0;
for(int i=0;i<m;i++){
int rowCnt=0;
for(int j=0;j<n;j++){
if(grid[i][j]!='0') continue;
if(j==0||grid[i][j-1]=='W'){
rowCnt=0;
for(int k=j+1;k<n;k++){
if(grid[i][k]=='W') break;
if(grid[i][k]=='E')
rowCnt++;
}
}
if(i==0||grid[i-1][j]=='W'){
colCnt[j]=0;
for(int c=i+1;c<m;c++){
if(grid[c][j]=='W') break;
if(grid[c][j]=='E')
colCnt[j]++;
}
}
res=max(res,colCnt[j]+rowCnt);
}
}
return res;
}