LintCode 598.僵尸矩阵

给一个二维网格,每一个格子都有一个值,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;
    }
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值