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. 【Hadoop离线基础总结】MapReduce案例之自定义groupingComparator

    MapReduce案例之自定义groupingComparator 求取Top 1的数据 需求 求出每一个订单中成交金额最大的一笔交易 订单id 商品id 成交金额 Order_0000005 Pdt ...

  2. vue 如何实现 Input 输入框模糊查询方法

    原理:原生js的indexOf() 方法,该方法将从头到尾地检索数组,看它是否含有对应的元素.开始检索的位置在数组 start 处或数组的开头(没有指定 start 参数时).如果找到一个 item, ...

  3. Java 将鼠标改为图片的两种方法

    一 图片跟着鼠标移动,鼠标隐藏 int x,y; addMouseMotionListener(this);//设置鼠标监听 public void paint(Graphics g) {  g.dr ...

  4. go多种uuid生成方式

    package main import ( "fmt" "github.com/chilts/sid" "github.com/kjk/betterg ...

  5. Flutter不能做什么:局限性

    老孟导读:您在网络上一定看过很多Flutter如何优秀的.如何完美的文章,而这篇文章将会告诉你Flutter不能做什么,注意并不是Flutter的缺点,比如第三方插件少.Dart不流行等,在我看来这都 ...

  6. HTML学习——day1

    HTML是一种用于创建网页的标准标记语 注意:对于中文网页需要使用<meta charset=''utf-8''>声明编码,否则会出现乱码. HTML标签 <标签>内容< ...

  7. flask之CBV模式

    flask_cbv.py ''' flask中的CBV模式: (1)导入views模块: from flask import views (2)定义类,继承views.MethodView类: cla ...

  8. 使用php+mysql+xml完成一个调查问卷

    本人根据php典型模块与项目实战大全此书所完成的一个调查问卷,同时管理员可以进行修改调查内容 同时用到了一个css文件,借鉴于 http://www.wufangbo.com/div-css-vote ...

  9. js时间戳转为日期格式的方法

    Date.prototype.Format = function(fmt){ var o = { "M+" : this.getMonth()+1, //月份 "d+&q ...

  10. B. Sleepy Game 博弈搜索

    题意:给一个有向图和起点,然后只有一名选手,这名选手可以随意挪动棋子,最终不能动的时候走过的边为奇数边为Win并输出路径,否则如果有环输出Draw,否则输出Lose; 题目链接 知道状态数最多只有n* ...