749. 隔离病毒

病毒扩散得很快,现在你的任务是尽可能地通过安装防火墙来隔离病毒。

假设世界由二维矩阵组成,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 面防火墙,就有一小区域可以幸存,不被病毒感染。
注意不需要在世界边界建立防火墙。
示例 3:

输入: grid =
[[1,1,1,0,0,0,0,0,0],
[1,0,1,0,1,1,1,1,1],
[1,1,1,0,0,0,0,0,0]]
输出: 13
说明:
在隔离右边感染区域后,隔离左边病毒区域只需要 2 个防火墙了。

说明:

grid 的行数和列数范围是 [1, 50]。

grid[i][j] 只包含 0 或 1 。

题目保证每次选取感染区域进行隔离时,一定存在唯一一个对未感染区域的威胁最大的区域。

class Solution {
int n, m;
boolean[][] visited;
Set<Integer> set = new TreeSet<>();
public int containVirus(int[][] grid) {
int res = 0;
n = grid.length;
m = grid[0].length;
while (true){
visited = new boolean[n][m];
PriorityQueue<int[]> q = new PriorityQueue<>(((o1, o2) -> o2[0]-o1[0]));
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
if (!visited[i][j] && grid[i][j] == 1){
set.clear();
int barriers = dfs(grid, i, j);
int infected = set.size();
q.offer(new int[]{infected, barriers, index(i, j)});
}
}
}
if (q.size() == 0){
break;
}
int[] t = q.poll();
res += t[1];
dfs1(grid, t[2] / m, t[2] % m);
for (int i = 0; i < n; i++){
Arrays.fill(visited[i], false);
}
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
if (!visited[i][j] && grid[i][j] == 1){
dfs2(grid, i, j);
}
}
} }
return res;
} private void dfs2(int[][] grid, int i, int j) {
if (grid[i][j] == 2){
return;
}
visited[i][j] = true;
if (i - 1 >= 0 && !visited[i - 1][j]){
if (grid[i - 1][j] == 0){
grid[i - 1][j] = 1;
visited[i - 1][j] = true;
}else{
dfs2(grid, i - 1, j);
}
}
if (i + 1 < n && !visited[i + 1][j]){
if (grid[i + 1][j] == 0){
grid[i + 1][j] = 1;
visited[i + 1][j] = true;
}else{
dfs2(grid, i + 1, j);
}
}
if (j - 1 >= 0 && !visited[i][j - 1]){
if (grid[i][j - 1] == 0){
grid[i][j - 1] = 1;
visited[i][j - 1] = true;
}else{
dfs2(grid, i, j - 1);
}
}
if (j + 1 < m && !visited[i][j + 1]){
if (grid[i][j + 1] == 0){
grid[i][j + 1] = 1;
visited[i][j + 1] = true;
}else{
dfs2(grid, i, j + 1);
}
}
} private void dfs1(int[][] grid, int i, int j) {
grid[i][j] = 2;
if (i - 1 >= 0){
if (grid[i - 1][j] == 1){
dfs1(grid, i - 1, j);
}
}
if (i + 1 < n){
if (grid[i + 1][j] == 1){
dfs1(grid, i + 1, j);
}
}
if (j - 1 >= 0){
if (grid[i][j - 1] == 1){
dfs1(grid, i, j - 1);
}
}
if (j + 1 < m){
if (grid[i][j + 1] == 1){
dfs1(grid, i, j + 1);
}
}
} private int dfs(int[][] grid, int i, int j) {
if (grid[i][j] == 2){
return 0;
}
visited[i][j] = true;
int cur = 0;
if (i - 1 >= 0 && !visited[i - 1][j]){
if (grid[i - 1][j] == 0){
cur++;
set.add(index(i - 1, j));
}else{
cur += dfs(grid, i - 1, j);
}
}
if (i + 1 < n && !visited[i + 1][j]){
if (grid[i + 1][j] == 0){
cur++;
set.add(index(i + 1 ,j));
}else{
cur += dfs(grid, i + 1, j);
}
}
if (j - 1 >= 0 && !visited[i][j - 1]){
if (grid[i][j - 1] == 0){
cur++;
set.add(index(i, j - 1));
}else{
cur += dfs(grid, i, j - 1);
}
}
if (j + 1 < m && !visited[i][j + 1]){
if (grid[i][j + 1] == 0){
cur++;
set.add(index(i, j + 1));
}else{
cur += dfs(grid, i, j + 1);
}
}
return cur;
} private int index(int i, int j){
return m * i + j;
}
}

Java实现 LeetCode 749 隔离病毒(DFS嵌套)的更多相关文章

  1. Java实现 LeetCode 1111 有效括号的嵌套深度(阅读理解题,位运算)

    1111. 有效括号的嵌套深度 有效括号字符串 定义:对于每个左括号,都能找到与之对应的右括号,反之亦然.详情参见题末「有效括号字符串」部分. 嵌套深度 depth 定义:即有效括号字符串嵌套的层数, ...

  2. Java实现 LeetCode 529 扫雷游戏(DFS)

    529. 扫雷游戏 让我们一起来玩扫雷游戏! 给定一个代表游戏板的二维字符矩阵. 'M' 代表一个未挖出的地雷,'E' 代表一个未挖出的空方块,'B' 代表没有相邻(上,下,左,右,和所有4个对角线) ...

  3. Java for LeetCode 216 Combination Sum III

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...

  4. Java for LeetCode 212 Word Search II

    Given a 2D board and a list of words from the dictionary, find all words in the board. Each word mus ...

  5. Java for LeetCode 047 Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  6. [Swift]LeetCode749. 隔离病毒 | Contain Virus

    A virus is spreading rapidly, and your task is to quarantine the infected area by installing walls. ...

  7. Java for LeetCode 126 Word Ladder II 【HARD】

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...

  8. Java for LeetCode 098 Validate Binary Search Tree

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  9. Java for LeetCode 095 Unique Binary Search Trees II

    Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...

随机推荐

  1. LeetCode--LinkedList--160. Intersection of Two Linked Lists(Easy)

    160. Intersection of Two Linked Lists(Easy) 题目地址https://leetcode.com/problems/intersection-of-two-li ...

  2. Neo4j填坑记录-Neo4jClient建立节点、建立关系相关

    最近一个项目需要用到知识图谱,选用了neo4j图数据库,在这过程中遇到几个坑,记录一下 1.无法登录,疯狂提示“WebSocket connection failure. Due to securit ...

  3. BOM基础

    BOM基础 打开窗口 window.open('about:blank','_blank') 第一个参数是打开哪一个口,第二个参数是在哪里打开窗口. 关闭窗口 window.close() windo ...

  4. Linux 命令行下搜索工具大盘点,效率提高不止一倍!

    在 Linux 命令行下进行文本关键字的搜索,大家肯定第一时间会想到 grep 命令.grep 命令确实十分强大,但如果需要用到它更加灵活的功能时,可能命令就会显得十分复杂. 于是,为了简化 grep ...

  5. go 数组 字符串 切片

    数组 数组定义方式 var a [3]int // 定义长度为3的int型数组, 元素全部为0 var b = [...]int{1, 2, 3} // 定义长度为3的int型数组, 元素为 1, 2 ...

  6. (电脑连不上热点)电脑连上了WIFI,但是显示网络不可用怎么办?

    假如WIFI没有问题的话,那这个就是电脑网络堵塞的问题了,下面是解决的办法: 情况一 1.首先win键+R打开运行框,输入cmd 2.然后在命令行输入 ipconfig -release ipconf ...

  7. python 定义一个插入数据(可以插入到每个表中)通用的方法

    前提置要:想要写一个方法,这个方法是插入数据到数据表的方法,只需要提供表名称,字段名称,还有插入的值,只要调用这个方法就可以自动帮助你插入数据 以下是不断实践优化出来 原本的插入数据库中的代码应该是这 ...

  8. ES6,ES7,ES8 常用特性总结

    一. ES6(ES2015) 1. 变量 let 和常量 const var 的问题 可以重复声明,没有报错和警告 无法限制修改 没有块级作用域, { } let 和 const 不能重复声明 都是块 ...

  9. poj2226更改行列匹配建图

    Muddy Fields Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10961   Accepted: 4071 Des ...

  10. 用开源软件TrinityCore在Debian 10上搭建魔兽世界8.3.0.34220的服务器

    用开源软件TrinityCore在Debian 10上搭建魔兽世界8.3.0.34220的服务器 TrinityCore是魔兽世界(World of Warcraft)的开源的服务端.目前支持魔兽的3 ...