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. GUI_DOWNLOAD 下载乱码

    状况: 开发者打开正常,跨公司或跨企业打开异常. 跨App上传格式异常. 解决上述问题步骤: 1.用浏览器或可改变文件编码格式切换的软件打开文件(其他app上传正常文档格式,或跨公司打开正常文件)查看 ...

  2. 【HBase】HBase与MapReduce的集成案例

    目录 需求 步骤 一.创建maven工程,导入jar包 二.开发MapReduce程序 三.运行结果 HBase与MapReducer集成官方帮助文档:http://archive.cloudera. ...

  3. Matlab中 awgn 函数输入参数带有‘measured’ 时snr的含义

    MATLAB中awgn 函数可以为输入信号x 添加一定大小的噪声. out = awgn(in,snr,'measured');  是一种常见的使用方法,意思是在添加噪声前先测量一下输入信号的功率,再 ...

  4. etcd实现服务发现

    前言 etcd环境安装与使用文章中介绍了etcd的安装及v3 API使用,本篇将介绍如何使用etcd实现服务发现功能. 服务发现介绍 服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式 ...

  5. python--递归函数的学习

    递归:函数间接或者直接调用自己 递归分两个过程 1.往下调用,分解的过程 2.往上回溯,综合的过程 递归的条件: 一定要有结束的条件 例子:阶乘: def fun_a(n): #print(n) if ...

  6. SpringMVC 拦截返回值,并自定义

    有关取代mvc:annotation-driven使用自定义配置请看: http://blog.csdn.net/cml_blog/article/details/45222431 1.在项目开发中, ...

  7. 【基准测试】BenchmarkDotNet介绍

    BenchmarkDotNet 概述 BenchmarkDotNet helps you to transform methods into benchmarks, track their perfo ...

  8. express+mysql实现简单的登录功能

    登录页面图: node.js文件代码: const express=require("express"); const app=express(); const path=requ ...

  9. SSH三大框架知识点

    Hibernate ****************************************************************************************** ...

  10. POJ3693 Maximum repetition substring 后缀数组

    POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...