TS solution
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n\n# Complexity\n- Time 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity:\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\nclass Region {\n  // as need to de-dupe the elements.\n  // If N rows and M cols.\n  // Total elements = NxM.\n  // Given row and col calculate X as: X = row * M + col.\n  // Given X calculate row and col as: row = X / M and col = X % M.\n\n  // Infected nodes represented by 1.\n  infected = new Set<number>();\n\n  // Uninfected neighbors represented by 0 are the ones this region can infect if not contained.\n  uninfectedNeighbors = new Set<number>();\n\n  // Number of walls required to contain all the infected nodes (1s) in this region.\n  // Note that two infected 1s can infect the same 0, so in this case we need two walls to save one 0 from two 1s.\n  wallsRequired = 0;\n}\n\nfunction containVirus(grid: number[][]): number {\n  if (grid == null || grid.length == 0) {\n    return 0;\n  }\n\n  const rows = grid.length;\n  const cols = grid[0].length;\n\n  let result = 0;\n\n  while (true) {\n    const regions: Region[] = [];\n\n    // Find all the regions using DFS (or can also use BFS).\n    const visited = new Array(rows).fill(false).map(() => new Array(cols).fill(false));\n    for (let row = 0; row < rows; row++) {\n      for (let col = 0; col < cols; col++) {\n        if (grid[row][col] == 1 && !visited[row][col]) {\n          const region = new Region();\n          dfs(grid, row, col, visited, region);\n\n          // Add region to list of regions only if it can cause infection.\n          if (region.uninfectedNeighbors.size > 0) {\n            regions.push(region);\n          }\n        }\n      }\n    }\n\n    // No more regions that can cause further infection, we are done.\n    if (regions.length == 0) {\n      break;\n    }\n\n    // Sort the regions. Region which can infected most neighbors first.\n    regions.sort((o1, o2) => {\n      return o2.uninfectedNeighbors.size - o1.uninfectedNeighbors.size;\n    });\n\n    // Build wall around region which can infect most neighbors.\n    const regionThatCauseMostInfection = regions.shift();\n    result += regionThatCauseMostInfection.wallsRequired;\n\n    for (const neighbor of regionThatCauseMostInfection.infected) {\n      const row = Math.floor(neighbor / cols);\n      const col = neighbor % cols;\n\n      // Choosing 2 as to denote that this cell is now contained\n      // and will not cause any more infection.\n      grid[row][col] = 2;\n    }\n\n    // For remaining regions, expand (neighbors are now infected).\n    for (const region of regions) {\n      for (const neighbor of region.uninfectedNeighbors) {\n        const row = Math.floor(neighbor / cols);\n        const col = neighbor % cols;\n        grid[row][col] = 1;\n      }\n    }\n  }\n\n  return result;\n}\n\n\nfunction dfs(grid: number[][], row: number, col: number, visited: boolean[][], region: Region) {\n  const rows = grid.length;\n  const cols = grid[0].length;\n\n  if (row < 0 || row >= rows || col < 0 || col >= cols || grid[row][col] == 2) {\n    return;\n  }\n\n  if (grid[row][col] == 1) {\n    // 1 is already infected.\n    // Add to the list, since we are using Set it will be deduped if added multiple times.\n    region.infected.add(row * cols + col);\n\n    // If already visited, return as we do not want to go into infinite recursion.\n    if (visited[row][col]) {\n      return;\n    }\n  }\n\n  visited[row][col] = true;\n\n  if (grid[row][col] == 0) {\n    // If 0 it is uninfected neighbor, we need a wall.\n    // Remeber we can reach this 0 multiple times from different infected neighbors i.e. 1s,\n    // and this will account for numbers of walls need to be built around this 0.\n    region.wallsRequired++;\n\n    // Add to uninfected list, it will be de-duped as we use Set.\n    region.uninfectedNeighbors.add(row * cols + col);\n    return;\n  }\n\n  // Visit neighbors.\n  dfs(grid, row + 1, col, visited, region);\n  dfs(grid, row - 1, col, visited, region);\n  dfs(grid, row, col + 1, visited, region);\n  dfs(grid, row, col - 1, visited, region);\n}\n```
['TypeScript']