[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
grid
will each be in the range[1, 50]
. - Each
grid[i][j]
will be either0
or1
. - Throughout the described process, there is always a contiguous viral region that will infect strictly more uncontaminated squares in the next round.
Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 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++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 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; } }; |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构