Lengthy But Simple Java Solution
IntuitionThe solution is simple. We need to keep doing dfs/bfs until and unless all the infection is spread or blocked.ApproachKeep track of infected nodes and
# Intuition
The solution is simple. We need to keep doing dfs/bfs until and unless all the infection is spread or blocked.

# Approach
Keep track of infected nodes and non infected nodes through bfs/dfs at each step. This will let us know which island of nodes to close such infection is minimal.

# Complexity
- Time complexity:
O((m×n)×(m×n+m×nlog(m×n)))

- Space complexity:
O(m×n) 

# Code
```java []
class Data {
    int len; // number of non infected
    List<int []> non; // list of cordinates of non infected
    List<int []> inf; // list of cordinates of infected
    int gates;  // gates required to block the spread
    Data(int len, int gates, List<int []> non, List<int []> inf) {
        this.len = len;
        this.non = non;
        this.inf = inf;
        this.gates = gates;
    }
}
class Solution {
    int x[] = {1, 0, -1, 0};
    int y[] = {0, 1, 0, -1};
    boolean vis[][];
    Data bfs(int mat[][], int sx, int sy) {
        Queue<int[]> qu = new LinkedList<>();
        int n = mat[0].length;
        int m = mat.length;
        int cnt = 0;
        int gates = 0;
        qu.add(new int[]{sx, sy});
        vis[sx][sy] = true;
        List<int []>  non = new ArrayList<>();
        List<int []> inf = new ArrayList<>();
        boolean visnI[][] = new boolean[50][50];
        inf.add(new int[]{sx, sy});
        while(!qu.isEmpty()) {
            int []temp = qu.poll();
            int a = temp[0];
            int b = temp[1];
            for(int i=0;i<4;i++) {
                    int p = a + x[i];
                    int q = b + y[i];
                    if(p >=0 && q >= 0 && p < m && q < n) {
                        if(mat[p][q] == 0) {
                            non.add(new int[]{p ,q});
                            if(visnI[p][q] == false) { // count distinct number of non infected which can be spread
                                cnt++; 
                                visnI[p][q] =true;
                            }
                            gates++; // gates required to close the infection, it can come from any infected node
                        } else if(mat[p][q] == 1 && vis[p][q] == false) {
                            qu.add(new int[]{p,q});
                            inf.add(new int[]{p,q});
                            vis[p][q] = true;
                        }
                    }
                }
        }
        return new Data(cnt, gates, non, inf);
    }

    public int containVirus(int[][] mat) {
       int m = mat.length;
       int n = mat[0].length;
       int ans= 0;
       while(true) { 
          vis = new boolean[m][n];
            PriorityQueue<Data> pq = new PriorityQueue<>((a, b) -> {
                return b.len - a.len;
            });
          for(int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {    
                if(mat[i][j] == 1 && vis[i][j] == false) { 
                    Data res = bfs(mat, i, j);
                    pq.add(res);
                }
            }
          }

          if(pq.isEmpty())  
            break;

          Data temp = pq.poll();
          ans+=temp.gates;

          for(int []d: temp.inf) {
            mat[d[0]][d[1]] = -1;  // Mark -1 to block the infection such that it does not gets picked up in the bfs
          }

          while(!pq.isEmpty()) {
            Data rex = pq.poll();
            for(int []t: rex.non)
                mat[t[0]][t[1]] = 1;   // Mark 1 to spread the infection where gate is not closed
          }

        return ans; 
    }   
}
```
['Java']