Skip to content

Commit 7a2b0bf

Browse files
authored
Update 749-contain-virus.js
1 parent 0b86f92 commit 7a2b0bf

File tree

1 file changed

+54
-84
lines changed

1 file changed

+54
-84
lines changed

749-contain-virus.js

Lines changed: 54 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -2,104 +2,74 @@
22
* @param {number[][]} grid
33
* @return {number}
44
*/
5-
const containVirus = function (grid) {
6-
const R = grid.length
7-
const C = grid[0].length
8-
let ans = 0
9-
const dirs = [
10-
[0, 1],
11-
[0, -1],
12-
[1, 0],
13-
[-1, 0],
14-
]
5+
const containVirus = (grid) => {
6+
const m = grid.length;
7+
const n = grid[0].length;
8+
let ans = 0;
159
while (true) {
16-
let walls = process(grid)
17-
ans += walls
18-
if (walls === 0) break
19-
}
20-
return ans
21-
function process(grid) {
22-
let maxArea = 0,
23-
ans = 0,
24-
color = -1,
25-
row = -1,
26-
col = -1
27-
// visited virus as 1, visited 0 using different color to indicate being affected by different virus
28-
29-
let visited = Array.from({ length: R }, () => Array(C).fill(0))
30-
31-
// find the max zero area.
32-
for (let i = 0; i < R; i++) {
33-
for (let j = 0; j < C; j++) {
34-
if (grid[i][j] === 1 && visited[i][j] === 0) {
35-
const walls = [0]
36-
const area = dfs(grid, visited, i, j, color, walls)
37-
if (area > maxArea) {
38-
maxArea = area
39-
ans = walls[0]
40-
row = i
41-
col = j
42-
}
43-
color-- // different islands using different color
10+
// list of regions can spread virus
11+
const regions = [];
12+
const visited = Array.from({ length: m }, () => Array(n).fill(false));
13+
for (let i = 0; i < m; i++) {
14+
for (let j = 0; j < n; j++) {
15+
if (grid[i][j] === 1 && !visited[i][j]) {
16+
const region = new Region();
17+
dfs(grid, i, j, region, visited);
18+
if (region.uninfected.size > 0) regions.push(region);
4419
}
4520
}
4621
}
4722

48-
removeIsland(grid, row, col)
49-
// spread by one step
50-
visited = Array.from({ length: R }, () => Array(C).fill(0))
51-
for (let i = 0; i < R; i++) {
52-
for (let j = 0; j < C; j++) {
53-
if (grid[i][j] === 1 && visited[i][j] === 0) {
54-
spread(grid, visited, i, j)
55-
}
23+
if (regions.length === 0) break;
24+
regions.sort((a, b) => a.uninfected.size - b.uninfected.size);
25+
let idx = -1, wall = -Infinity
26+
for(let i = 0, len = regions.length; i < len; i++) {
27+
if(regions[i].uninfected.size > wall) {
28+
wall = regions[i].uninfected.size
29+
idx = i
5630
}
5731
}
58-
return ans
59-
}
60-
function dfs(grid, visited, r, c, color, walls) {
61-
if (r < 0 || r > R - 1 || c < 0 || c > C - 1) return 0
62-
if (grid[r][c] === 0) {
63-
walls[0]++
64-
if (visited[r][c] === color) return 0
65-
visited[r][c] = color
66-
return 1
67-
}
68-
if (visited[r][c] === 1 || grid[r][c] !== 1) return 0
69-
visited[r][c] = 1
70-
let ans = 0
71-
for (let dir of dirs) {
72-
const x = r + dir[0]
73-
const y = c + dir[1]
74-
ans += dfs(grid, visited, x, y, color, walls)
32+
const mostToBeInfected = regions[idx]
33+
ans += mostToBeInfected.wallNeeded
34+
regions.splice(idx, 1)
35+
for (let x of mostToBeInfected.infected) {
36+
let i = (x / n) >> 0,
37+
j = x % n;
38+
grid[i][j] = 2;
7539
}
76-
return ans
77-
}
7840

79-
function removeIsland(grid, r, c) {
80-
if (r < 0 || r > R - 1 || c < 0 || c > C - 1 || grid[r][c] !== 1) return
81-
grid[r][c] = -1
82-
for (let dir of dirs) {
83-
const x = r + dir[0]
84-
const y = c + dir[1]
85-
removeIsland(grid, x, y)
41+
for (let region of regions) {
42+
for (let x of region.uninfected) {
43+
let i = (x / n) >> 0,
44+
j = x % n;
45+
grid[i][j] = 1;
46+
}
8647
}
8748
}
8849

89-
function spread(grid, visited, r, c) {
90-
if (r < 0 || r > R - 1 || c < 0 || c > C - 1 || visited[r][c] === 1) return
91-
if (grid[r][c] === -1) return
92-
visited[r][c] = 1
93-
if (grid[r][c] === 0) {
94-
grid[r][c] = 1
95-
return
96-
}
97-
for (let dir of dirs) {
98-
const x = r + dir[0]
99-
const y = c + dir[1]
100-
spread(grid, visited, x, y)
50+
return ans;
51+
function dfs(grid, i, j, region, visited) {
52+
if (i < 0 || i == m || j < 0 || j == n) return;
53+
54+
if (grid[i][j] === 1 && !visited[i][j]) {
55+
visited[i][j] = true;
56+
region.infected.add(i * n + j);
57+
dfs(grid, i - 1, j, region, visited);
58+
dfs(grid, i + 1, j, region, visited);
59+
dfs(grid, i, j - 1, region, visited);
60+
dfs(grid, i, j + 1, region, visited);
61+
} else if (grid[i][j] === 0) {
62+
region.wallNeeded += 1;
63+
region.uninfected.add(i * n + j);
10164
}
10265
}
66+
};
67+
class Region {
68+
constructor() {
69+
this.wallNeeded = 0;
70+
this.infected = new Set();
71+
this.uninfected = new Set();
72+
}
10373
}
10474

10575
// another

0 commit comments

Comments
 (0)