leetcode 749. Contain Virus

本文探讨了在一个二维网格世界中,如何通过安装防火墙来阻止病毒蔓延的算法。使用并查集找到连续的病毒区域,并根据每个区域可能感染的健康单元格数量决定优先级,以最小化感染扩散。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 moreuncontaminated squares in the next round.

请这位同学好好审题。。。。

解题思路:使用union find找连通的病毒块,每一个病毒块将感染的细胞数量和需要建立的防火墙数量是不一样的。所以需要一个unordered_map存储每个病毒块的细胞集合,key为病毒块的根细胞的秩;一个unordered_map存储每个病毒块将感染的细胞集合,,key为病毒块的根细胞的秩;一个unordered_map存储每个病毒块需要建立的防火墙的数量;

根据题意,首先为将感染细胞数量最多的病毒块建立防火墙,不是我理解的需要建立防火墙数目最多的病毒块建立防火墙。。。

class Solution {
public:
    int containVirus(vector<vector<int>>& grid) 
    {
        int rows = grid.size() , cols = grid[0].size() ;
        vector<int> dir = { -1 , 0 , 1 , 0 , -1} ;
        int res = 0 ; int cnt = 0 ;
        
        while(true)
        {
            root = vector<int>(rows * cols , -1) ;
            for(int i = 0 ; i < rows * cols ; i++) root[i] = i ;
            unordered_map<int , unordered_set<int>> virus , infecteds ;
            unordered_map<int , int > walls ;
            int non_infs = 0 , mx_infs = 0 , key = -1 ; 
            for(int i = 0 ; i < rows ; ++i)
                for(int j = 0 ; j < cols ; ++j)
                {
                    if(grid[i][j] == 0)
                    {
                        non_infs++ ;
                        continue ;
                    }
                    else if(grid[i][j] == -1) continue ;
                    
                    set<int> new_infs ;
                    int rt = find(i * cols + j) ;
                    
                    for(int k = 0 ; k < 4 ; ++k)
                    {
                        int new_i = i + dir[k] , new_j = j + dir[k + 1] ;
                        if(new_i < 0 || new_i >= rows || new_j < 0 || new_j >= cols) continue ;
                        if(grid[new_i][new_j] == 0) 
                        {
                            new_infs.insert(new_i * cols + new_j) ;
                            continue ;
                        }
                        else if(grid[new_i][new_j] == 1) 
                        {
                            int x = find(new_i * cols + new_j) ;
                            rt = merge(rt , x , virus , infecteds , walls) ;
                        }
                    }
                    
                    virus[rt].insert(i * cols + j) ;
                    infecteds[rt].insert(new_infs.begin() , new_infs.end()) ;
                    walls[rt] += new_infs.size() ;
                    
                    if(infecteds[rt].size() > mx_infs) 
                    {
                        mx_infs = infecteds[rt].size() ;
                        key = rt ;
                    }
                    
                }
            
            if(non_infs == 0 || mx_infs == 0) return res ;
            
            for(auto ele : virus[key]) grid[ele / cols][ele % cols] = -1 ;
            res += walls[key] ;
            infecteds.erase(key) ;
            for(auto ele : infecteds)
            {
                for(auto e : ele.second) grid[e / cols][e % cols] = 1 ;
            }
            cnt++;
        }
        
        return res ;
    }
    
    int find(int i)
    {
        return root[i] == i ? i : find(root[i]) ;
    }
    
    int merge(int i , int j , unordered_map<int , unordered_set<int>>& virus , unordered_map<int , unordered_set<int>>& infecteds , unordered_map<int, int>& walls)
    {
        int x = find(i) , y = find(j) ;
        if(x < y)
        {
            root[y] = x ;
            virus[x].insert(virus[y].begin() , virus[y].end()) ;
            virus.erase(y) ;
            infecteds[x].insert(infecteds[y].begin() , infecteds[y].end()) ;
            infecteds.erase(y) ;
            walls[x] += walls[y] ;
            walls.erase(y) ;
            return x ;
        }
        else if(x > y)
        {
            root[x] = y ;
            virus[y].insert(virus[x].begin() , virus[x].end()) ;
            virus.erase(x) ;
            infecteds[y].insert(infecteds[x].begin() , infecteds[x].end()) ;
            infecteds.erase(x) ;
            walls[y] += walls[x] ;
            walls.erase(x) ;
            return y ;
        }
        return x ;
    }
    
private:
    vector<int> root ;
};

 

### 如何在 VSCode 中安装和配置 LeetCode 插件以及 Node.js 运行环境 #### 安装 LeetCode 插件 在 VSCode 的扩展市场中搜索 `leetcode`,找到官方提供的插件并点击 **Install** 按钮进行安装[^1]。如果已经安装过该插件,则无需重复操作。 #### 下载与安装 Node.js 由于 LeetCode 插件依赖于 Node.js 环境,因此需要下载并安装 Node.js。访问官方网站 https://nodejs.org/en/ 并选择适合当前系统的版本(推荐使用 LTS 版本)。按照向导完成安装流程后,需确认 Node.js 是否成功安装到系统环境中[^2]。 可以通过命令行运行以下代码来验证: ```bash node -v npm -v ``` 上述命令应返回对应的 Node.js 和 npm 的版本号。如果没有正常返回版本信息,则可能未正确配置环境变量。 #### 解决环境路径问题 即使完成了 Node.js 的安装,仍可能出现类似 “LeetCode extension needs Node.js installed in environment path” 或者 “command ‘leetcode.toggleLeetCodeCn’ not found” 的错误提示[^3]。这通常是因为 VSCode 未能识别全局的 Node.js 路径或者本地安装的 nvm 默认版本未被正确加载[^4]。 解决方法如下: 1. 手动指定 Node.js 可执行文件的位置 在 VSCode 设置界面中输入关键词 `leetcode`,定位至选项 **Node Path**,将其值设为实际的 Node.js 安装目录下的 `node.exe` 文件位置。例如:`C:\Program Files\nodejs\node.exe`。 2. 使用 NVM 用户管理工具调整默认版本 如果通过 nvm 工具切换了不同的 Node.js 版本,请确保设置了默认使用的版本号。可通过以下指令实现: ```bash nvm alias default <version> ``` 重新启动 VSCode 后测试功能键是否恢复正常工作状态。 --- #### 配置常用刷题语言 最后一步是在 VSCode 设置面板中的 LeetCode 插件部分定义个人习惯采用的主要编程语言作为默认提交方式之一。这样可以减少频繁修改编码风格的时间成本。 --- ### 总结 综上所述,要在 VSCode 上顺利启用 LeetCode 插件及其关联服务,除了基本插件本身外还需额外准备支持性的后台框架——即 Node.js 应用程序引擎;同时针对特定场景下产生的兼容性障碍采取针对性措施加以修正即可达成目标[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值