Contain Virus LeetCode solution in JavaScript

1
var containVirus = function (isInfected) {
2
const directions = [
3
[1, 0],
4
[-1, 0],
5
[0, 1],
6
[0, -1],
7
];
8
let walls = 0;
9

10
function findContaminated() {
11
let visited = {},
12
infected = [];
13
let mostViral;
14
for (let i = 0; i < isInfected.length; i++) {
15
for (let j = 0; j < isInfected[i].length; j++) {
16
if (isInfected[i][j] === 1) {
17
let key = `${i}-${j}`;
18
if (key in visited) continue;
19
else infected.push([i, j]);
20

21
let zeroes = new Set();
22
let perimeter = findPerimeter(i, j, visited, zeroes);
23

24
// Find the largest potential infection perimeter based on the number of 0's neighboring infected cells
25
if (!mostViral) mostViral = { i, j, perimeter, zeroes: zeroes.size };
26
else if (zeroes.size > mostViral.zeroes)
27
mostViral = { i, j, perimeter, zeroes: zeroes.size };
28
}
29
}
30
}
31
if (mostViral) {
32
walls += mostViral.perimeter;
33

34
// Quarantine the most viral area
35
quarantine(mostViral.i, mostViral.j);
36

37
// Spread the infection throughout the remaining infected areas
38
let alreadyInfected = {};
39
for (let [row, col] of infected) {
40
if (mostViral.i === row && mostViral.j === col) continue;
41
else infect(row, col, alreadyInfected);
42
}
43
return true;
44
}
45
return false;
46
}
47

48
while (findContaminated()) continue;
49
return walls;
50

51
function findPerimeter(row, col, visited, zeroes) {
52
if (
53
row < 0 ||
54
col < 0 ||
55
row >= isInfected.length ||
56
col >= isInfected[0].length
57
)
58
return 0;
59
let key = `${row}-${col}`;
60

61
// If the current cell is visited or quarantined, leave the perimeter unchanged
62
if (visited[key] || isInfected[row][col] === -1) return 0;
63

64
// If the current cell is not infected and not quarantined, increase the perimeter
65
if (isInfected[row][col] === 0) {
66
zeroes.add(key);
67
return 1;
68
}
69

70
visited[key] = true;
71
let perimeter = 0;
72
for (let [r, c] of directions) {
73
perimeter += findPerimeter(row + r, col + c, visited, zeroes);
74
}
75
return perimeter;
76
}
77

78
function quarantine(row, col) {
79
if (
80
row < 0 ||
81
col < 0 ||
82
row >= isInfected.length ||
83
col >= isInfected[0].length
84
)
85
return;
86

87
// Only quarantine infected cells and neighboring infected cells
88
if (isInfected[row][col] === 1) isInfected[row][col] = -1;
89
else return;
90

91
for (let [r, c] of directions) quarantine(row + r, col + c);
92
}
93

94
function infect(row, col, alreadyInfected, neighbor = 0) {
95
if (
96
row < 0 ||
97
col < 0 ||
98
row >= isInfected.length ||
99
col >= isInfected[0].length
100
)
101
return;
102
let key = `${row}-${col}`;
103

104
// If the current cell is already infected or quarantined
105
if (alreadyInfected[key] || isInfected[row][col] === -1) return;
106

107
// If the current cell is clear but neighbors an infected cell, infect it
108
if (isInfected[row][col] === 0 && neighbor === 1) {
109
alreadyInfected[key] = true;
110
return (isInfected[row][col] = 1);
111
} else if (isInfected[row][col] === 1 && neighbor === 1) {
112
alreadyInfected[key] = true;
113
neighbor = 0;
114
}
115

116
for (let [r, c] of directions)
117
infect(row + r, col + c, alreadyInfected, neighbor + 1);
118
}
119
};

0

WPM •0 •0

100%

ACC •0 •0

0s

TIME •0