[LeetCode] 749. Contain Virus 包含病毒
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:
- The number of rows and columns of
gridwill each be in the range[1, 50]. - Each
grid[i][j]will be either0or1. - 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 包含病毒的更多相关文章
- [LeetCode] Contain Virus 包含病毒
A virus is spreading rapidly, and your task is to quarantine the infected area by installing walls. ...
- Java实现 LeetCode 749 隔离病毒(DFS嵌套)
749. 隔离病毒 病毒扩散得很快,现在你的任务是尽可能地通过安装防火墙来隔离病毒. 假设世界由二维矩阵组成,0 表示该区域未感染病毒,而 1 表示该区域已感染病毒.可以在任意 2 个四方向相邻单元之 ...
- [LeetCode] Contains Duplicate III 包含重复值之三
Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...
- [LeetCode] Contains Duplicate II 包含重复值之二
Given an array of integers and an integer k, return true if and only if there are two distinct indic ...
- [LeetCode] 217. Contains Duplicate 包含重复元素
Given an array of integers, find if the array contains any duplicates. Your function should return t ...
- Virus:病毒查杀
简介 小伙伴们,大家好,今天分享一次Linux系统杀毒的经历,还有个人的一些总结,希望对大家有用. 这次遇到的是一个挖矿的病毒,在挖一种叫门罗币(XMR)的数字货币,行情走势请看 https://ww ...
- hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- [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 ...
- [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 ...
随机推荐
- docker镜像里的tag那些事--alpine,slim,stretch,jessie
https://stackoverflow.com/questions/54954187/docker-images-types-slim-vs-slim-stretch-vs-stretch-vs- ...
- 最全 webpak4.0 打包性能优化清单
最全 webpak4.0 打包性能优化清单 webpack4.0如何进行打包优化? 无非是从两个角度进行优化,其一:优化打包速度,其二:优化打包体积,送你一份打包性能优化清单 1.使用loader的时 ...
- C#中的WinForm的消息机制简述,及消息机制下Invoke,和BeginInvoke的使用和区别
在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate,至于委托的本质请参考我的另一随笔:对.net事件的看法. 一.为什么Control类提供了Invoke和Begin ...
- PageHelper分页正确用法
依赖和配置就不说了,说用法 Page<Object> page = PageHelper.startPage(pageNum, pageSize); List<SysRoleDTO& ...
- 【项目管理工具】—— Microsoft Office Project 介绍
Project是由微软开发的项目管理软件.设计的目的在于协助项目经理发展计划,为任务分配资源.跟踪计划.管理预算和分析工作量. 对于我们之前的项目来说,之前的整体计划和WBS任务分解都是通过Excel ...
- Fiddler抓包工具使用指南|手机安装Fiddler的安全证书
Fiddler 4 1.设置: Tools -> Telerik Fiddler Options 勾选远程 手机安装证书 ->使用Android手机的浏览器打开:http://10.2. ...
- H5利用formData来上传文件(包括图片,doc,pdf等各种格式)方法小结!
H5页面中我们常需要进行文件上传,那么怎么来实现这个功能呢??? 我主要谈如下两种方法. (一).传统的form表单方法 <form action="/Home/SaveFile1&q ...
- Dump文件定制工具---MiniDump Wizard
MiniDump向导应用程序允许在不编写代码的情况下尝试MiniDumpWriteDump和MiniDumpCallback函数.可以指定将传递给MiniDumpWriteDump函数的MINIDUM ...
- 悲伤的 C++ throw(…)
当在C++语言中引入异常时,引入了相应的throw(…)动态异常说明符,注释了哪些异常可以由函数抛出.比如: // this function might throw an integer or a ...
- nodejs+nvm历史版本
官网:http://nodejs.org/dist/ 淘宝镜像:https://npm.taobao.org/mirrors/node/ nvm历史版本:https://github.com/core ...