-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path0928-minimize-malware-spread-ii.js
More file actions
100 lines (87 loc) · 2.8 KB
/
0928-minimize-malware-spread-ii.js
File metadata and controls
100 lines (87 loc) · 2.8 KB
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* Minimize Malware Spread II
* Time Complexity: O(I * N^2)
* Space Complexity: O(N * I)
*/
var minMalwareSpread = function (graph, initial) {
const totalNodes = graph.length;
const infectedSourceLookup = new Set(initial);
initial.sort((firstElement, secondElement) => firstElement - secondElement);
const infectedSources = initial;
const nodeContagionSources = new Array(totalNodes).fill(null).map(() => []);
for (
let sourceIterator = 0;
sourceIterator < infectedSources.length;
sourceIterator++
) {
const currentSourceCandidate = infectedSources[sourceIterator];
const currentlyReachableNodes = new Set();
const exploredNodesDuringBFS = new Set(infectedSourceLookup);
exploredNodesDuringBFS.delete(currentSourceCandidate);
const explorationQueue = [currentSourceCandidate];
while (explorationQueue.length > 0) {
const processingNode = explorationQueue.shift();
currentlyReachableNodes.add(processingNode);
for (
let adjacentNodeIndex = 0;
adjacentNodeIndex < totalNodes;
adjacentNodeIndex++
) {
if (
graph[processingNode][adjacentNodeIndex] === 1 &&
!exploredNodesDuringBFS.has(adjacentNodeIndex)
) {
exploredNodesDuringBFS.add(adjacentNodeIndex);
explorationQueue.push(adjacentNodeIndex);
}
}
}
for (
let graphNodeIndex = 0;
graphNodeIndex < totalNodes;
graphNodeIndex++
) {
if (
currentlyReachableNodes.has(graphNodeIndex) &&
!infectedSourceLookup.has(graphNodeIndex)
) {
nodeContagionSources[graphNodeIndex].push(currentSourceCandidate);
}
}
}
const potentialSavesPerSource = new Map();
for (
let targetNodeIndex = 0;
targetNodeIndex < totalNodes;
targetNodeIndex++
) {
if (nodeContagionSources[targetNodeIndex].length === 1) {
const uniqueSource = nodeContagionSources[targetNodeIndex][0];
potentialSavesPerSource.set(
uniqueSource,
(potentialSavesPerSource.get(uniqueSource) || 0) + 1,
);
}
}
let maximumNodesPreserved = -1;
let bestRemovalCandidate = infectedSources[0];
for (
let candidateIterator = 0;
candidateIterator < infectedSources.length;
candidateIterator++
) {
const currentInitialNode = infectedSources[candidateIterator];
const nodesSavedByRemoval =
potentialSavesPerSource.get(currentInitialNode) || 0;
if (nodesSavedByRemoval > maximumNodesPreserved) {
maximumNodesPreserved = nodesSavedByRemoval;
bestRemovalCandidate = currentInitialNode;
} else if (
nodesSavedByRemoval === maximumNodesPreserved &&
currentInitialNode < bestRemovalCandidate
) {
bestRemovalCandidate = currentInitialNode;
}
}
return bestRemovalCandidate;
};