lintcode598- Zombie in Matrix- medium

Given a 2D grid, each cell is either a wall 2, a zombie 1or people 0 (the number zero, one, two).Zombies can turn the nearest people(up/down/left/right) into zombies every day, but can not through wall. How long will it take to turn all people into zombies? Return -1 if can not turn all people into zombies.

Example

Given a matrix:

0 1 2 0 0
1 0 0 2 1
0 1 0 0 0

return 2

 

1. BFS。queue+size层级遍历。第一层是初始的僵尸。每天晚上推入僵尸旁边的新僵尸(注意处理过的僵尸不用再次处理了,因为不会再有影响,靠周围那圈才是新生力量)。遍历的同时用一个count记录剩余人类。人减到0终止遍历,或者queue空了终止遍历(僵尸不够格)。

2.for循环。子函数每天做僵尸的咬人转换。主函数每天找到所有僵尸都做一次transfer。这个比较简单,但会有重复僵尸,效率不如前面的高。

细节:1.变量定义,最前面最好写下int ZOMBIE = 1; 这种,更直观。2.这种矩阵的都小心索引边界确认+dxdy简洁写法。3.二维数组调用还是统一下吧,函数头写int x, int y,矩阵调用也用int[x][y],x和h比,y和w比。相当于把x看成向下指的坐标轴,y看成向右指的坐标轴,这样也自洽的。4. dxdy写法规范直接int[] dx = {-1, 0, 1, 0}; 等号右边不用写int说明

1.BFS:

public class Solution {
    /*
     * @param grid: a 2D integer grid
     * @return: an integer
     */
    
    private class Point {
        int x;
        int y;
        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    
    public int zombie(int[][] grid) {
        // write your code here
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return -1;
        }
        int h = grid.length;
        int w = grid[0].length;
        int HUMAN = 0;
        int ZOMBIE = 1;
        int WALL = 2;
        int[] dx = {-1, 0, 1, 0};
        int[] dy = {0, -1, 0, 1};
        
        int humanCnt = 0;
        int dayCnt = 0;
        Queue<Point> queue = new LinkedList<Point>();
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                if (grid[i][j] == HUMAN) {
                    humanCnt++;
                } else if (grid[i][j] == ZOMBIE) {
                    queue.offer(new Point(i,j));
                }
            }
        }
        
        if (humanCnt == 0) {
            return 0;
        }
        
        while (!queue.isEmpty()) {
            dayCnt++;
            // 你一开始忘了层级遍历!!!傻了把,那你就是每一个僵尸咬一次就加一天了
            int size = queue.size();
            for(int c = 0; c < size; c++) {
                Point crt = queue.poll();
                for (int i = 0; i < 4; i++) {
                    int cx = crt.x + dx[i];
                    int cy = crt.y + dy[i];
                    if (isValid(grid, cx, cy) && grid[cx][cy] == HUMAN) {
                        grid[cx][cy] = ZOMBIE;
                        queue.offer(new Point(cx,cy));
                        humanCnt--;
                        if (humanCnt == 0) {
                            return dayCnt;
                    }
                }
            }
            }
            
        }
        
        return -1;
    }
    
    private boolean isValid(int[][] grid, int x, int y) {
        int h = grid.length;
        int w = grid[0].length;
        return x >= 0 && x < h && y >= 0 && y < w;
    }
}

2.for循环

public class Solution {
    /*
     * @param grid: a 2D integer grid
     * @return: an integer
     */
    public int zombie(int[][] grid) {
        // write your code here
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return -1;
        }
        
        int h = grid.length;
        int w = grid[0].length;
        boolean hasChange = true;
        int dayCount =0;
        
        while (hasChange) {
            dayCount++;
            hasChange = false;
            for (int i = 0; i < h; i++) {
                for(int j = 0; j < w; j++) {
                    if (grid[i][j] == 1 && transfer(grid, i, j)) {
                        hasChange = true;
                    }
                }
            }
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    if (grid[i][j] == 3) {
                        grid[i][j] = 1;
                    }
                }
            }
        }
        
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                if (grid[i][j] == 0) {
                    return -1;
                }
            }
        }
        return dayCount - 1;
    }
    
    private boolean transfer(int[][] grid, int x, int y) {
        
        int[] dx = {-1, 0, 1, 0};
        int[] dy = {0, -1, 0, 1};
        boolean hasChange = false;
        
        for (int i = 0; i < 4; i++) {
            int cx = x + dx[i];
            int cy = y + dy[i];
            if (isValid(grid, cx, cy) && grid[cx][cy] == 0) {
                grid[cx][cy] = 3;
                hasChange = true;
            }
        }
        return hasChange;
    }
    
    private boolean isValid(int[][] grid, int x, int y) {
        int h = grid.length;
        int w = grid[0].length;
        
        return x >= 0 && x < h && y >= 0 && y < w;
    }
}
原文地址:https://www.cnblogs.com/jasminemzy/p/7745905.html