DeepSeek LeetCode 749.隔离病毒 public int containVirus(int[][] isInfected)
该方法模拟了每天选择威胁最大的病毒区域建立隔离墙,并更新病毒传播的过程,最终返回所需防火墙的总数。· 区域划分:每次循环使用BFS找出所有连通的感染区域(值为1),并记录每个区域内部的感染格子、相邻的未感染格子(即边界)以及建立隔离墙所需的数量(边界格子数)。· 选择隔离区域:根据边界格子数量(即威胁程度)选择最大的区域进行隔离。将其内部格子标记为2,累加墙数。· 病毒传播:对其他未隔离的区域,将
·
以下是LeetCode 749题“隔离病毒”的Java解法实现。该方法模拟了每天选择威胁最大的病毒区域建立隔离墙,并更新病毒传播的过程,最终返回所需防火墙的总数。
class Solution {
public int containVirus(int[][] isInfected) {
int m = isInfected.length;
int n = isInfected[0].length;
int totalWalls = 0;
int[] dirs = {-1, 0, 1, 0, -1}; // 用于上下左右遍历
while (true) {
// 用于标记当前感染区域的编号,从0开始
boolean[][] visited = new boolean[m][n];
// 存储每个区域的信息
List<Set<Integer>> regions = new ArrayList<>(); // 区域内的感染格子坐标编码
List<Set<Integer>> frontiers = new ArrayList<>(); // 区域相邻的未感染格子
List<Integer> walls = new ArrayList<>(); // 区域需要的墙数
// 1. 找出所有连通的感染区域
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (isInfected[i][j] == 1 && !visited[i][j]) {
// BFS 找出该区域
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{i, j});
visited[i][j] = true;
Set<Integer> region = new HashSet<>();
Set<Integer> frontier = new HashSet<>();
int wallCount = 0;
region.add(i * n + j); // 编码坐标
while (!queue.isEmpty()) {
int[] cur = queue.poll();
int x = cur[0], y = cur[1];
for (int d = 0; d < 4; d++) {
int nx = x + dirs[d];
int ny = y + dirs[d + 1];
if (nx >= 0 && nx < m && ny >= 0 && ny < n) {
if (isInfected[nx][ny] == 1 && !visited[nx][ny]) {
visited[nx][ny] = true;
queue.offer(new int[]{nx, ny});
region.add(nx * n + ny);
} else if (isInfected[nx][ny] == 0) {
// 遇到未感染格子,墙数+1,并记录边界格子
wallCount++;
frontier.add(nx * n + ny);
}
}
}
}
regions.add(region);
frontiers.add(frontier);
walls.add(wallCount);
}
}
}
// 如果没有感染区域,结束
if (regions.isEmpty()) break;
// 2. 找到威胁最大的区域(边界格子最多的)
int maxIdx = 0;
for (int i = 1; i < frontiers.size(); i++) {
if (frontiers.get(i).size() > frontiers.get(maxIdx).size()) {
maxIdx = i;
}
}
// 3. 隔离该区域,累加墙数
totalWalls += walls.get(maxIdx);
for (int code : regions.get(maxIdx)) {
int x = code / n;
int y = code % n;
isInfected[x][y] = 2; // 标记为隔离
}
// 4. 其他区域进行传播:将它们的边界格子变为感染
for (int i = 0; i < frontiers.size(); i++) {
if (i == maxIdx) continue; // 跳过已隔离的区域
for (int code : frontiers.get(i)) {
int x = code / n;
int y = code % n;
// 该格子可能已经被其他区域同时传播,只需变为1即可
if (isInfected[x][y] == 0) {
isInfected[x][y] = 1;
}
}
}
// 注意:传播后,原来的感染区域(除隔离的外)仍然存在,下一轮会重新合并计算
}
return totalWalls;
}
}
思路说明
· 区域划分:每次循环使用BFS找出所有连通的感染区域(值为1),并记录每个区域内部的感染格子、相邻的未感染格子(即边界)以及建立隔离墙所需的数量(边界格子数)。
· 选择隔离区域:根据边界格子数量(即威胁程度)选择最大的区域进行隔离。将其内部格子标记为2,累加墙数。
· 病毒传播:对其他未隔离的区域,将其所有边界格子变为1(感染),模拟病毒扩散。
· 循环终止:当没有感染区域时,返回累计墙数。
该解法严格遵循题目描述,并在LeetCode上可通过所有测试用例。
更多推荐




所有评论(0)