zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    SQL SERVER 表分区技术
    T-SQL 查询某个表的约束(包含触发器trigger)
    该数据库标记为 SUSPECT解决方法
    DevExpressGridHelper
    DevExpress MVC Gridview 把header caption 替换为 CheckBox (类似select all)
    CSRF漏洞
    XSS闯关挑战(1-15)
    Nginx 解析漏洞
    Nginx 配置错误导致漏洞
    Nginx 文件名逻辑漏洞(CVE-2013-4547)
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7745905.html
Copyright © 2011-2022 走看看