美文网首页工作生活
LeetCode 749. 隔离病毒

LeetCode 749. 隔离病毒

作者: 风卷晨沙 | 来源:发表于2019-07-11 12:52 被阅读0次

1、题目

749. 隔离病毒

2、题解

首先这道题是真的麻烦,稍微一不注意就爆炸了。我也是写了很多次才正儿八经的写对了。
我们一步一步来解析一下,首先是题意,这道题要我们求的是给病毒扩散的矩阵设置防火墙,求这个墙壁的数量。而且一次只能给一片区域设置,所以A区域设置之后,B区域依然在感染。我们要得到,最后设置的防火墙的数量。
开始计算。
第一步,是梳理大致流程,就是既然每一次都只能给一片区域进行安装防火墙,那么我们就可以写一个方法来得到,当前最大的使用防火墙的数量,将这部分防火墙数量进行输出,并将这部分的病毒设置为不活动的状态,在之后的比较中不把这个第一次最大的区域拿来进行比较。
然后将每一次最大的防火墙数量进行累加,即可得到结果。

第二步,如何来写这个方法?首先,写一个双层for循环来遍历当前数组grid,并使用dp数组stateArray来记录状态,写一个DFS方法来计算出当前点相连的病毒区域即将感染的面积maxArea;对这个maxArea值和当前最大的感染面积cnt进行判断,谁大,与之相关的参数就设置为谁的。这样的循环遍历,就已经得到了第一次的最大值。该方法的返回值就输出对应的墙壁数量即可。注意:这个地方之所以我没有直接使用int walls,而是使用了wall.walls;是因为基本数据类型在方法中是纯粹的值传递,无论在方法中如何改变,都不会使得方法外的参数改变。而使用引用数据类型的对象类型的话,虽然从本质上来讲,java只有值传递,没有引用传递。但是引用类型的参数,传递的是栈内存中的指向堆内存内容的地址值,所以,虽然也是进行的值传递,但由于操作的是同一个地址,所以可以保留下修改的内容,从而实现我们想要的结果。

第三步,完善后续,使得这个方法可以不断的得到当前最大感染面积及相关参数。
这部分应当分为两部分,第一部分是将当前最大感染面积的部分设置为-1的不活动状态,使得这部分不会感染其他区域;第二部分是对于进行了第一步之后的当前状态,进行病毒感染操作,从而得到一个新的当前矩形区域数组。

第四步,完成第一步的整体流程设计,循环累加得到结果即可。

3、代码

 class Solution {
        public int containVirus(int[][] grid) {
            int result=0;
            while (true){
                int walls=process(grid);
                if (walls==0){
                    break;
                }
                result+=walls;
            }
            return result;
        }

        //对整个场景进行业务逻辑梳理
        private int process(int[][] grid) {
            int rows = grid.length;
            int cols = grid[0].length;
            // cnt 是最大面积,ans是对应的墙
            int cnt = 0, res = 0, color = -1, row = -1, col = -1;
            //用一个数组来装当前这个点的状态
            int[][] stateArray=new int[rows][cols];
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    if(grid[i][j]==1&&stateArray[i][j]==0){
                        Wall wall = new Wall();
                        wall.walls=0;
                        int maxArea = getMaxAreaDfs(grid, stateArray, i, j, color, wall);
                        if(maxArea>cnt){
                            cnt=maxArea;
                            res=wall.walls;
                            row=i;
                            col=j;
                        }
                        color--;
                    }
                }
            }
            //修墙,将目标区域设置为未活动
            buildWall(grid,row,col);
            //另一块传播病毒
//            spread(grid,stateArray,row,col);
            stateArray=new int[rows][cols];
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    if (grid[i][j] == 1 && stateArray[i][j] == 0){
                        spread(grid, stateArray, i, j);
                    }
                }
            }
            return res;

        }

        private void spread(int[][] grid, int[][] stateArray, int row, int col) {
            int rows = grid.length;
            int cols = grid[0].length;
            if (row < 0 || row >= rows || col < 0 || col >= cols || stateArray[row][col] == 1) {
                return;
            }
            if (grid[row][col] == 0){
                grid[row][col] = 1;
                stateArray[row][col] = 1;
            }else if (grid[row][col] == 1){
                stateArray[row][col] = 1;
                int[] dir = { -1, 0, 1, 0, -1 };
                for (int i = 0; i < 4; i++){
                    spread(grid, stateArray, row + dir[i], col + dir[i + 1]);
                }
            }
        }

        private void buildWall(int[][] grid, int row, int col) {
            int rows = grid.length;
            int cols = grid[0].length;
            if (row < 0 || row >= rows || col < 0 || col >= cols || grid[row][col] != 1){
                return;
            }
            //设置为不活动
            grid[row][col] = -1;
            int[] dir = { -1, 0, 1, 0, -1 };
            //DFS
            for (int i = 0; i < 4; i++){
                buildWall(grid, row + dir[i], col + dir[i + 1]);
            }
        }

        private int getMaxAreaDfs(int[][] grid, int[][] stateArray, int row, int col, int color, Wall wall) {
            int rows = grid.length;
            int cols = grid[0].length;
            int res = 0;
            //异常排除
            if (row < 0 || row >= rows || col < 0 || col >= cols){
                return 0;
            }
            //0不是病毒
            if (grid[row][col] == 0) {
                wall.walls++;
                //第二次进入
                if (stateArray[row][col] == color){
                    return 0;
                }
                //第一次进入
                stateArray[row][col] = color;
                return 1;
            }
            // 不是grid[i][j]==1 or 0
            if (stateArray[row][col] == 1 || grid[row][col] != 1){
                return 0;
            }
            //grid[i][j]==1
            stateArray[row][col] = 1;
            //前后左右,再来一次,直到出现不再是1的结果。DFS的思想。
            int[] dir = { -1, 0, 1, 0, -1 };
            for (int i = 0; i < 4; i++){
                res += getMaxAreaDfs(grid,stateArray, row + dir[i], col + dir[i + 1], color, wall);
            }
            return res;
        }

        class Wall{
            public int walls;

        }

    }

4、执行结果

image.png

相关文章

  • LeetCode 749. 隔离病毒

    1、题目 749. 隔离病毒 2、题解 首先这道题是真的麻烦,稍微一不注意就爆炸了。我也是写了很多次才正儿八经的写...

  • 病毒隔离

    如今食宿自理 老板无影无踪

  • 「文案」对ta的真情告白💕

    ❶ 口罩会隔离病毒,但不会隔离爱。 ❷ ...

  • 网络学习第一天

    隔离病毒不隔离爱,隔离病毒也不能隔离学习的热情,方法总比困难多,我们迎来了空中黔课的开播了,这种全新的上...

  • 隔离病毒不隔离爱

    2020.03.05 星期四 晴 昨晚和妹妹妹夫商量好,妹夫今天去上班顺便给公婆送药,我们让他带一些...

  • 隔离病毒不能隔离爱

    文艺版 她说你任何为人称道的美丽, 不及他第一次遇见你。 ——《南山南》 相思相见知何日?此时此夜难为情。 ——李...

  • 隔离病毒,但不隔离爱

    “千门万户曈曈日,总把新桃换旧符”,除夕之夜,万家灯火,本该是团团圆圆,阖家欢乐之时,但新型冠状病毒席卷中华...

  • 隔离病毒,但不隔离爱 ️️️️🙌

    最近看了很多关于疫情的新闻,我有很多很多的感想。 疫情是命令十万火急,防控是责任刻不容缓。当前,全国各地疫...

  • 隔离病毒不隔离爱

    2020年,谁都没想到率先迎来的不是欣喜而是一场冰冷的新冠肺炎疫情今年的“2·14”情人节,注定不平凡!有一群人,...

  • 隔离病毒不隔离爱

    2020年2月13日,教体局张书记、宋主席等一行四人,莅临王集乡第一初级中学指导“新冠状病毒”疫情防控工作。张书记...

网友评论

    本文标题:LeetCode 749. 隔离病毒

    本文链接:https://www.haomeiwen.com/subject/cbtlhctx.html