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

The world is modeled as a 2-D array of cells, where 0 represents uninfected cells, and 1 represents cells contaminated with the virus. A wall (and only one wall) can be installed between any two 4-directionally adjacent cells, on the shared boundary.

Every night, the virus spreads to all neighboring cells in all four directions unless blocked by a wall. Resources are limited. Each day, you can install walls around only one region -- the affected area (continuous block of infected cells) that threatens the most uninfected cells the following night. There will never be a tie.

Can you save the day? If so, what is the number of walls required? If not, and the world becomes fully infected, return the number of walls used.

Example 1:

Input: 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]]
Output: 10
Explanation:
There are 2 contaminated regions.
On the first day, add 5 walls to quarantine the viral region on the left. The board after the virus spreads is: [[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]] On the second day, add 5 walls to quarantine the viral region on the right. The virus is fully contained.

Example 2:

Input: grid =
[[1,1,1],
[1,0,1],
[1,1,1]]
Output: 4
Explanation: Even though there is only one cell saved, there are 4 walls built.
Notice that walls are only built on the shared boundary of two different cells.

Example 3:

Input: 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]]
Output: 13
Explanation: The region on the left only builds two new walls.

Note:

  1. The number of rows and columns of grid will each be in the range [1, 50].
  2. Each grid[i][j] will be either 0 or 1.
  3. Throughout the described process, there is always a contiguous viral region that will infect strictly more uncontaminated squares in the next round.

Python:

class Solution(object):
def containVirus(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
directions = [(0, 1), (0, -1), (-1, 0), (1, 0)] def dfs(grid, r, c, lookup, regions, frontiers, perimeters):
if (r, c) in lookup:
return
lookup.add((r, c))
regions[-1].add((r, c))
for d in directions:
nr, nc = r+d[0], c+d[1]
if not (0 <= nr < len(grid) and \
0 <= nc < len(grid[r])):
continue
if grid[nr][nc] == 1:
dfs(grid, nr, nc, lookup, regions, frontiers, perimeters)
elif grid[nr][nc] == 0:
frontiers[-1].add((nr, nc))
perimeters[-1] += 1 result = 0
while True:
lookup, regions, frontiers, perimeters = set(), [], [], []
for r, row in enumerate(grid):
for c, val in enumerate(row):
if val == 1 and (r, c) not in lookup:
regions.append(set())
frontiers.append(set())
perimeters.append(0)
dfs(grid, r, c, lookup, regions, frontiers, perimeters) if not regions: break triage_idx = frontiers.index(max(frontiers, key = len))
for i, region in enumerate(regions):
if i == triage_idx:
result += perimeters[i]
for r, c in region:
grid[r][c] = -1
continue
for r, c in region:
for d in directions:
nr, nc = r+d[0], c+d[1]
if not (0 <= nr < len(grid) and \
0 <= nc < len(grid[r])):
continue
if grid[nr][nc] == 0:
grid[nr][nc] = 1 return result

C++:

class Solution {
public:
int containVirus(vector<vector<int>>& grid) {
int res = 0, m = grid.size(), n = grid[0].size();
vector<vector<int>> dirs{{-1,0},{0,1},{1,0},{0,-1}};
while (true) {
unordered_set<int> visited;
vector<vector<vector<int>>> all;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1 && !visited.count(i * n + j)) {
queue<int> q{{i * n + j}};
vector<int> virus{i * n + j};
vector<int> walls;
visited.insert(i * n + j);
while (!q.empty()) {
auto t = q.front(); q.pop();
for (auto dir : dirs) {
int x = (t / n) + dir[0], y = (t % n) + dir[1];
if (x < 0 || x >= m || y < 0 || y >= n || visited.count(x * n + y)) continue;
if (grid[x][y] == -1) continue;
else if (grid[x][y] == 0) walls.push_back(x * n + y);
else if (grid[x][y] == 1) {
visited.insert(x * n + y);
virus.push_back(x * n + y);
q.push(x * n + y);
}
}
}
unordered_set<int> s(walls.begin(), walls.end());
vector<int> cells{(int)s.size()};
all.push_back({cells ,walls, virus});
}
}
}
if (all.empty()) break;
sort(all.begin(), all.end(), [](vector<vector<int>> &a, vector<vector<int>> &b) {return a[0][0] > b[0][0];});
for (int i = 0; i < all.size(); ++i) {
if (i == 0) {
vector<int> virus = all[0][2];
for (int idx : virus) grid[idx / n][idx % n] = -1;
res += all[0][1].size();
} else {
vector<int> wall = all[i][1];
for (int idx : wall) grid[idx / n][idx % n] = 1;
}
}
}
return res;
}
};

   

All LeetCode Questions List 题目汇总

[LeetCode] 749. Contain Virus 包含病毒的更多相关文章

  1. [LeetCode] Contain Virus 包含病毒

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

  2. Java实现 LeetCode 749 隔离病毒(DFS嵌套)

    749. 隔离病毒 病毒扩散得很快,现在你的任务是尽可能地通过安装防火墙来隔离病毒. 假设世界由二维矩阵组成,0 表示该区域未感染病毒,而 1 表示该区域已感染病毒.可以在任意 2 个四方向相邻单元之 ...

  3. [LeetCode] Contains Duplicate III 包含重复值之三

    Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...

  4. [LeetCode] Contains Duplicate II 包含重复值之二

    Given an array of integers and an integer k, return true if and only if there are two distinct indic ...

  5. [LeetCode] 217. Contains Duplicate 包含重复元素

    Given an array of integers, find if the array contains any duplicates. Your function should return t ...

  6. Virus:病毒查杀

    简介 小伙伴们,大家好,今天分享一次Linux系统杀毒的经历,还有个人的一些总结,希望对大家有用. 这次遇到的是一个挖矿的病毒,在挖一种叫门罗币(XMR)的数字货币,行情走势请看 https://ww ...

  7. hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. [LeetCode] 219. Contains Duplicate II 包含重复元素 II

    Given an array of integers and an integer k, find out whether there are two distinct indices i and j ...

  9. [LeetCode] 220. Contains Duplicate III 包含重复元素 III

    Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...

随机推荐

  1. K8s基本概念入门

    序言 没等到风来,绵绵小雨,所以写个随笔,聊聊k8s的基本概念. k8s是一个编排容器的工具,其实也是管理应用的全生命周期的一个工具,从创建应用,应用的部署,应用提供服务,扩容缩容应用,应用更新,都非 ...

  2. 加速Github访问

    Github 仓库的数据传输很慢,甚至可能导致仓库拉取失败.例如: remote: Enumerating objects: , done. remote: Counting objects: % ( ...

  3. Python中实现count(distinct )

    假设一个表有6个字段c1,c2,c3,c4,c5,c6,有如下的sql语句: select c1,count(distinct(c6)) from tbl where c3>1 group by ...

  4. LeetCode 818. Race Car

    原题链接在这里:https://leetcode.com/problems/race-car/ 题目: Your car starts at position 0 and speed +1 on an ...

  5. 数论--扩展欧几里得exgcd

    算法思想 我们想求得一组\(x,y\)使得 \(ax+by = \gcd(a,b)\) 根据 \(\gcd(a,b) = \gcd(b,a\bmod b)\) 如果我们现在有\(x',y'\) 使得 ...

  6. 【批处理】set命令

    原文地址:https://www.cnblogs.com/Braveliu/p/5081084.html [1]set命令简介 set,设置. [2]set命令使用 1. 打印系统环境变量.set命令 ...

  7. Log4net 单独创建配置文件(三)

    1.建立ASP.Net空的Web程序,添加Default.aspx窗体 2.添加web配置文件命名为:log4net.config,添加配置 <?xml version="1.0&qu ...

  8. linux命令之------快捷键说明

    linux快捷键说明 (1)命令或目录补齐:Tab (2)遍历历史记录:history 上移:ctrl+p,下移:ctrl+n (3)光标移动 左移:ctrl+b:右移:ctrl+f:移到首部:ctr ...

  9. 安卓入门教程(十三)-Activity

    已经发表个人公众号 什么是Activity? Android是由Activity,Service,Content,Provider等组件组成,其中要讲的就是Activity组件,这是最基本,且常用的组 ...

  10. lower_bound( )和upper_bound( )怎么用嘞↓↓↓

    lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的. 在从小到大的排序数组中, lower_bound( begin,end,num):从数 ...