LeetCode 749

题目

contain-virus

题目描述

病毒扩散得很快,现在你的任务是尽可能地通过安装防火墙来隔离病毒。
假设世界由二维矩阵组成,0 表示该区域未感染病毒,而 1 表示该区域已感染病毒。可以在任意 2 个四方向相邻单元之间的共享边界上安装一个防火墙(并且只有一个防火墙)。
每天晚上,病毒会从被感染区域向相邻未感染区域扩散,除非被防火墙隔离。现由于资源有限,每天你只能安装一系列防火墙来隔离其中一个被病毒感染的区域(一个区域或连续的一片区域),且该感染区域对未感染区域的威胁最大且保证唯一。
你需要努力使得最后有部分区域不被病毒感染,如果可以成功,那么返回需要使用的防火墙个数; 如果无法实现,则返回在世界被病毒全部感染时已安装的防火墙个数。
示例 1:
输入: grid =
[[0,1,0,0,0,0,0,1],
[0,1,0,0,0,0,0,1],
[0,0,0,0,0,0,0,1],
[0,0,0,0,0,0,0,0]]
输出: 10
说明:
一共有两块被病毒感染的区域: 从左往右第一块需要 5 个防火墙,同时若该区域不隔离,晚上将感染 5 个未感染区域(即被威胁的未感染区域个数为 5);
第二块需要 4 个防火墙,同理被威胁的未感染区域个数是 4。因此,第一天先隔离左边的感染区域,经过一晚后,病毒传播后世界如下:
[[0,1,0,0,0,0,1,1],
[0,1,0,0,0,0,1,1],
[0,0,0,0,0,0,1,1],
[0,0,0,0,0,0,0,1]]
第二题,只剩下一块未隔离的被感染的连续区域,此时需要安装 5 个防火墙,且安装完毕后病毒隔离任务完成。
示例 2:
输入: grid =
[[1,1,1],
[1,0,1],
[1,1,1]]
输出: 4
说明:
此时只需要安装 4 面防火墙,就有一小区域可以幸存,不被病毒感染。
注意不需要在世界边界建立防火墙。

题解

题目意思是对病毒区域建立防火墙进行隔离,但是在有两个条件

条件1:就是每天只能隔离一个病毒区域,并且每天没被隔离的病毒都会扩散一层,
条件2:每次选择隔离感染区域需对未感染区域的威胁最大且保证唯一

所以我们要做的
第一步就是寻找最大威胁感染区域并且统计需要的防火墙的个数
第二步把找到最大威胁感染区域在地图上清除
第三步没被隔离的病毒扩散一层
然后循环这些步骤知道找不到最大威胁感染区域
所以在第一步的时候我们遍历地图找到一个感染点然后对其标记并且通过深搜找到其所在的感染区域,在深搜的时候我们肯定会遇到未感染的点而遇到次数就是我们要建立的防火墙个数,但是我们要比较的是未感染的大小(因此我们每次搜索到未感染的点都要判断是否走过),所以我们要同时统计这两个数量 然后在搜索完成后返回。但是我们在一次遍历中可能会多次遇到同一个未感染的点所以在搜索中我们要对每个未感染的点进行涂色(不同的病毒区域可能会对一个点进行多次感染)当我们找到最大感染点的时候后面的步骤就简单了
ps: 要注意找到有相同的个数可感染范围的最大威胁感染区域时 要对他进行一个筛选并且选择使用防火墙个数多的那个
pss:当前提交代码可再优化 进行一些剪枝时间可以更加快 然而回家懒得改了。。。。。

代码

  class lc749 {

    int[][] map;
    int[][] visit;
    int[][] dir = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};

    public int containVirus(int[][] grid) {
        map = grid;
        int sum = 0;
        int[] max;
        if (grid.length == 0)
            return 0;
        int row = grid.length;
        int col = grid[0].length;
        int count = 1;
        int[] dit = new int[2];
        visit = new int[grid.length][grid[0].length];

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                System.out.print(" " + map[i][j]);
            }
            System.out.println("");
        }
        System.out.println("");

        while (true) {
            max = new int[]{0, 0};
            int flag = 1;
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    if (visit[i][j] == 0 && map[i][j] >= 1) {
                        visit[i][j] = 1;

                        int[] num = dfs(i, j, new int[]{0, 0}, flag);
                        if (num[0] > max[0]) {
                            max = num;
                            dit[0] = i;
                            dit[1] = j;
                        } else if (num[0] == max[0] && num[1] > max[1]) {
                            max = num;
                            dit[0] = i;
                            dit[1] = j;
                        }
                        flag++;
                    }
                }
            }
            if (max[0] == 0)
                break;
            map[dit[0]][dit[1]] = -1;
            clear1(dit[0], dit[1]);
            getNext(row, col, count);
            visit = new int[grid.length][grid[0].length];
            sum += max[1];
            count++;
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    System.out.print(" " + map[i][j]);
                }
                System.out.println("");
            }
            System.out.println("");

        }
        return sum;
    }

    private void getNext(int row, int col, int count) {
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (map[i][j] == 0) {
                    for (int k = 0; k < 4; k++) {
                        if (i + dir[k][0] >= 0 && i + dir[k][0] < map.length && j + dir[k][1] >= 0 && j + dir[k][1] < map[0].length)
                            if (map[i + dir[k][0]][j + dir[k][1]] <= count && map[i + dir[k][0]][j + dir[k][1]] > 0) {
                                map[i][j] = count + 1;
                                break;
                            }
                    }
                }
            }
        }
    }

    public void clear1(int row, int col) {
        for (int i = 0; i < 4; i++) {
            if (row + dir[i][0] >= 0 && row + dir[i][0] < map.length && col + dir[i][1] >= 0 && col + dir[i][1] < map[0].length)
                if (map[row + dir[i][0]][col + dir[i][1]] > 0) {
                    map[row + dir[i][0]][col + dir[i][1]] = -1;
                    clear1(row + dir[i][0], col + dir[i][1]);
                }
        }
    }

    public int[] dfs(int row, int col, int[] sum, int flag) {
        for (int i = 0; i < 4; i++) {
            if (row + dir[i][0] >= 0 && row + dir[i][0] < map.length && col + dir[i][1] >= 0 && col + dir[i][1] < map[0].length)
                if (map[row + dir[i][0]][col + dir[i][1]] == 0) {
                    if (visit[row + dir[i][0]][col + dir[i][1]] != flag)
                        sum[0]++;
                    visit[row + dir[i][0]][col + dir[i][1]] = flag;
                    sum[1]++;
                } else if (map[row + dir[i][0]][col + dir[i][1]] == -1) {
                } else {
                    if (visit[row + dir[i][0]][col + dir[i][1]] == 1)
                        continue;
                    visit[row + dir[i][0]][col + dir[i][1]] = 1;
                    sum = dfs(row + dir[i][0], col + dir[i][1], sum, flag);
                }
        }
        return sum;
    }
}

提交截图

image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,820评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,648评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,324评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,714评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,724评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,328评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,897评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,804评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,345评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,431评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,561评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,238评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,928评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,417评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,528评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,983评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,573评论 2 359

推荐阅读更多精彩内容

  • 专业考题类型管理运行工作负责人一般作业考题内容选项A选项B选项C选项D选项E选项F正确答案 变电单选GYSZ本规程...
    小白兔去钓鱼阅读 9,012评论 0 13
  • 网络安全是指网络系统的硬件、软件及其系统中的数据受到保护,不因偶然的或者恶意的原因而遭受到破坏、更改、泄露,系统连...
    不吃土豆的洋芋阅读 3,249评论 0 42
  • 1 产品概述 是指一种将内部网和公众访问网(如Internet)分开的方法,它实际上是一种建立在现代通信网络技术和...
    得奕阅读 683评论 0 1
  • 一、防火分区 (一)厂房的防火分区 1.单层厂房 (1)甲类 1)一级、4000㎡。 2)二级、3000㎡。 (2...
    灰丫蛋阅读 6,458评论 0 0
  • 定位,虽然从产品开始,但是可以是一项服务一家公司,一个机构,甚至是个人,等等,那么最贴近的就是每个人都可以打造自己...
    綦有理阅读 263评论 0 0