给一个二维网格,每一个格子都有一个值,2 代表墙,1 代表僵尸,0 代表人类(数字 0, 1, 2)。僵尸每天可以将上下左右最接近的人类感染成僵尸,但不能穿墙。将所有人类感染为僵尸需要多久,如果不能感染所有人则返回 -1。
1.创建一个内部类 代表一个位置 其属性为横纵坐标
2.用for循环对数组进行遍历 初始化人类数量并把僵尸位置存入队列
3.BFS遍历 注意是按层遍历 即用一个size变量记录当前队列中元素数量
然后for循环size次 保证每一轮遍历都是当前的僵尸 没有新感染的僵尸
4.每感染一个人类 人类数量减1 每进行一轮遍历 天数加1 直到人类剩余数量为0 返回天数
public class Solution {
class Coodinate{
int x;
int y;
public Coodinate(int x, int y){
this.x = x;
this.y = y;
}
}
private static final int PEOPLE = 0;
private static final int WALL = 2;
private static final int ZOMBIE = 1;
public int zombie(int[][] grid) {
if(grid == null || grid.length == 0 || grid[0].length == 0)
return 0;
int[][] directions = {{0,1},{1,0},{0,-1},{-1,0}};
int remainPeople = 0;
int days = 0;
Queue<Coodinate> zombie = new LinkedList<>();
for(int i = 0; i < grid.length; i++){
for(int j = 0; j < grid[0].length; j++){
if(grid[i][j] == ZOMBIE)
zombie.offer(new Coodinate(i,j));
else if(grid[i][j] == PEOPLE)
remainPeople++;
}
}
while(!zombie.isEmpty()){
days++;
int size = zombie.size();
for(int j = 0; j < size; j++){
Coodinate coo = zombie.poll();
for(int i = 0; i < 4; i++){
Coodinate adj = new Coodinate(coo.x + directions[i][0], coo.y + directions[i][1]);
if(isPeople(adj, grid)){
zombie.offer(adj);
grid[adj.x][adj.y] = ZOMBIE;
remainPeople--;
}
if(remainPeople == 0)
return days;
}
}
}
return -1;
}
public boolean isPeople(Coodinate coo, int[][] grid){
if(coo.x < 0 || coo.y < 0 || coo.x >= grid.length || coo.y >= grid[0].length)
return false;
if(grid[coo.x][coo.y] == PEOPLE)
return true;
return false;
}
}