尽量减少恶意软件的传播 II
难度:
标签:
题目描述
代码结果
运行时间: 47 ms, 内存: 20.3 MB
/*
* 思路:
* 1. 使用DFS(深度优先搜索)来找到每个节点可以感染的所有节点。
* 2. 计算每个初始感染节点的贡献值,即移除该节点后,减少的感染节点数。
* 3. 返回贡献值最大的节点,如果有多个,返回索引最小的节点。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int minMalwareSpread(int[][] graph, int[] initial) {
int n = graph.length;
int[] infectedBy = new int[n];
Arrays.fill(infectedBy, -1);
for (int node : initial) {
dfs(graph, node, node, infectedBy, new boolean[n]);
}
int[] contribution = new int[n];
IntStream.range(0, n).filter(i -> infectedBy[i] != -1).forEach(i -> contribution[infectedBy[i]]++);
return Arrays.stream(initial)
.boxed()
.min((a, b) -> contribution[a] != contribution[b] ? Integer.compare(contribution[b], contribution[a]) : Integer.compare(a, b))
.orElse(-1);
}
private void dfs(int[][] graph, int start, int infected, int[] infectedBy, boolean[] visited) {
if (visited[start]) return;
visited[start] = true;
infectedBy[start] = infected;
for (int i = 0; i < graph.length; i++) {
if (graph[start][i] == 1 && !visited[i]) {
dfs(graph, i, infected, infectedBy, visited);
}
}
}
}
解释
方法:
这个题解的思路是通过深度优先搜索(DFS)来探索每个初始感染节点的影响范围,以确定在移除某个初始感染节点后,能够最大程度减少网络中感染的节点数量。首先,使用一个数组 `initial_record` 来标记哪些节点是初始感染节点。对每个初始感染节点进行测试,即假设将其移除,然后使用DFS来计算如果移除该节点后,由该节点直接或间接连接的节点中,有多少节点会被感染。对于每个通过DFS访问的节点,如果它是一个初始感染节点,就立即停止进一步的搜索。这样可以模拟该节点被移除后的情况。最后,选择能够使最终感染节点数最小化的节点,如果有多个节点都能达到最小化效果,则返回索引最小的节点。
时间复杂度:
O(k * (n + m))
空间复杂度:
O(n)
代码细节讲解
🦆
在题解中,为什么在DFS过程中遇到初始感染节点就立即停止搜索?这种处理方式对结果有什么影响?
▷🦆
题解中提到了在DFS中进行回溯,标记节点未访问,并将节点标记为感染。这种回溯操作在算法中起到了什么作用?是否存在潜在的错误或逻辑不一致?
▷🦆
题解描述了一个'最终感染节点数最小化'的目标。请问这个目标是如何通过算法实现的?具体的逻辑是什么?
▷