3
private static final int[][] DIR = new int[][] {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};5
public int containVirus(int[][] isInfected) {6
int m = isInfected.length, n = isInfected[0].length;10
// infected regions, sorted desc according to the number of nearby12
PriorityQueue<Region> pq = new PriorityQueue<Region>();13
// already visited cells14
boolean[][] visited = new boolean[m][n];17
for (int i = 0; i < m; i++) {18
for (int j = 0; j < n; j++) {20
// if current cell is infected, and it's not visited21
if (isInfected[i][j] != 1 || visited[i][j]) continue;23
// we found a new region, dfs to find all the infected24
// and uninfected cells in the current region25
Region reg = new Region();26
dfs(i, j, reg, isInfected, visited, new boolean[m][n], m, n);28
// if there are some uninfected nodes in this region,29
// we can contain it, so add it to priority queue30
if (reg.uninfected.size() != 0) pq.offer(reg);34
// if there are no regions to contain, break35
if (pq.isEmpty()) break;37
// Contain region with most uninfected nodes38
Region containReg = pq.poll();39
ans += containReg.wallsRequired;41
// use (2) to mark a cell as contained42
for (int[] cell : containReg.infected) isInfected[cell[0]][cell[1]] = 2;44
// Spread infection to uninfected nodes in other regions45
while (!pq.isEmpty()) {46
Region spreadReg = pq.poll();48
for (int[] cell : spreadReg.uninfected) isInfected[cell[0]][cell[1]] = 1;60
boolean[][] uninfectedVis,64
reg.addInfected(i, j);66
for (int[] dir : DIR) {70
// continue, if out of bounds OR contained OR already visited71
if (di < 0 || dj < 0 || di == m || dj == n || grid[di][dj] == 2 || visited[di][dj]) continue;73
// if neighbour node is not infected74
if (grid[di][dj] == 0) {75
// a wall will require to stop the spread from cell (i,j) to (di, dj)78
// if this uninfected node is not already visited for current region79
if (!uninfectedVis[di][dj]) {80
uninfectedVis[di][dj] = true;81
reg.addUninfected(di, dj);83
} else dfs(di, dj, reg, grid, visited, uninfectedVis, m, n);88
class Region implements Comparable<Region> {89
public List<int[]> infected;90
public List<int[]> uninfected;91
public int wallsRequired;94
infected = new ArrayList();95
uninfected = new ArrayList();98
public void addInfected(int row, int col) {99
infected.add(new int[] {row, col});102
public void addUninfected(int row, int col) {103
uninfected.add(new int[] {row, col});107
public int compareTo(Region r2) {108
return Integer.compare(r2.uninfected.size(), uninfected.size());