Java implements LeetCode 749 virus isolation (DFS nesting)

749. Virus quarantine

Viruses are spreading quickly, and now your task is to isolate the virus by installing a firewall as much as possible.

Suppose the world is composed of a two-dimensional matrix, 0 indicates that the area is not infected with viruses, and 1 indicates that the area is infected with viruses. A firewall (and only one firewall) can be installed on the shared boundary between any two four-directional adjacent units.

Every night, the virus will spread from the infected area to the adjacent uninfected area unless it is isolated by the firewall. Due to limited resources, you can only install a series of firewalls every day to isolate one of the virus-infected areas (one area or a continuous area), and the infected area poses the greatest threat to the uninfected area and is guaranteed to be unique.

You need to work hard to ensure that some areas are not infected by viruses. If it can be successful, then return the number of firewalls that need to be used; if it is not possible, then return the number of firewalls that were installed when the world was completely infected by viruses.

示例 1:

输入: grid = 
[[0,1,0,0,0,0,0,1],
 [0,1,0,0,0,0,0,1],
 [0,0,0,0,0,0,0,1],
 [0,0,0,0,0,0,0,0]]
输出: 10
说明:
一共有两块被病毒感染的区域: 从左往右第一块需要 5 个防火墙,同时若该区域不隔离,晚上将感染 5 个未感染区域(即被威胁的未感染区域个数为 5;
第二块需要 4 个防火墙,同理被威胁的未感染区域个数是 4。因此,第一天先隔离左边的感染区域,经过一晚后,病毒传播后世界如下:
[[0,1,0,0,0,0,1,1],
 [0,1,0,0,0,0,1,1],
 [0,0,0,0,0,0,1,1],
 [0,0,0,0,0,0,0,1]]
第二题,只剩下一块未隔离的被感染的连续区域,此时需要安装 5 个防火墙,且安装完毕后病毒隔离任务完成。
示例 2:

输入: grid = 
[[1,1,1],
 [1,0,1],
 [1,1,1]]
输出: 4
说明: 
此时只需要安装 4 面防火墙,就有一小区域可以幸存,不被病毒感染。
注意不需要在世界边界建立防火墙。
 
示例 3:

输入: grid = 
[[1,1,1,0,0,0,0,0,0],
 [1,0,1,0,1,1,1,1,1],
 [1,1,1,0,0,0,0,0,0]]
输出: 13
说明: 
在隔离右边感染区域后,隔离左边病毒区域只需要 2 个防火墙了。
 

Explanation:

The range of grid rows and columns is [1, 50].
grid [i] [j] contains only 0 or 1.
The problem ensures that each time an infected area is selected for isolation, there must be only one area that poses the greatest threat to the uninfected area.

class Solution {
     int n, m;
    boolean[][] visited;
    Set<Integer> set = new TreeSet<>();
    public int containVirus(int[][] grid) {
        int res = 0;
        n = grid.length;
        m = grid[0].length;
        while (true){
            visited = new boolean[n][m];
            PriorityQueue<int[]> q = new PriorityQueue<>(((o1, o2) -> o2[0]-o1[0]));
            for (int i = 0; i < n; i++){
                for (int j = 0; j < m; j++){
                    if (!visited[i][j] && grid[i][j] == 1){
                        set.clear();
                        int barriers = dfs(grid, i, j);
                        int infected = set.size();
                        q.offer(new int[]{infected, barriers, index(i, j)});
                    }
                }
            }
            if (q.size() == 0){
                break;
            }
            int[] t = q.poll();
            res += t[1];
            dfs1(grid, t[2] / m, t[2] % m);
            for (int i = 0; i < n; i++){
                Arrays.fill(visited[i], false);
            }
            for (int i = 0; i < n; i++){
                for (int j = 0; j < m; j++){
                    if (!visited[i][j] && grid[i][j] == 1){
                        dfs2(grid, i, j);
                    }
                }
            }

        }
        return res;
    }

    private void dfs2(int[][] grid, int i, int j) {
        if (grid[i][j] == 2){
            return;
        }
        visited[i][j] = true;
        if (i - 1 >= 0 && !visited[i - 1][j]){
            if (grid[i - 1][j] == 0){
                grid[i - 1][j] = 1;
                visited[i - 1][j] = true;
            }else{
                dfs2(grid, i - 1, j);
            }
        }
        if (i + 1 < n && !visited[i + 1][j]){
            if (grid[i + 1][j] == 0){
                grid[i + 1][j] = 1;
                visited[i + 1][j] = true;
            }else{
                dfs2(grid, i + 1, j);
            }
        }
        if (j - 1 >= 0 && !visited[i][j - 1]){
            if (grid[i][j - 1] == 0){
                grid[i][j - 1] = 1;
                visited[i][j - 1] = true;
            }else{
                dfs2(grid, i, j - 1);
            }
        }
        if (j + 1 < m && !visited[i][j + 1]){
            if (grid[i][j + 1] == 0){
                grid[i][j + 1] = 1;
                visited[i][j + 1] = true;
            }else{
                dfs2(grid, i, j + 1);
            }
        }
    }

    private void dfs1(int[][] grid, int i, int j) {
        grid[i][j] = 2;
        if (i - 1 >= 0){
            if (grid[i - 1][j] == 1){
                dfs1(grid, i - 1, j);
            }
        }
        if (i + 1 < n){
            if (grid[i + 1][j] == 1){
                dfs1(grid, i + 1, j);
            }
        }
        if (j - 1 >= 0){
            if (grid[i][j - 1] == 1){
                dfs1(grid, i, j - 1);
            }
        }
        if (j + 1 < m){
            if (grid[i][j + 1] == 1){
                dfs1(grid, i, j + 1);
            }
        }
    }


    private int dfs(int[][] grid, int i, int j) {
        if (grid[i][j] == 2){
            return 0;
        }
        visited[i][j] = true;
        int cur = 0;
        if (i - 1 >= 0 && !visited[i - 1][j]){
            if (grid[i - 1][j] == 0){
                cur++;
                set.add(index(i - 1, j));
            }else{
                cur += dfs(grid, i - 1, j);
            }
        }
        if (i + 1 < n && !visited[i + 1][j]){
            if (grid[i + 1][j] == 0){
                cur++;
                set.add(index(i + 1 ,j));
            }else{
                cur += dfs(grid, i + 1, j);
            }
        }
        if (j - 1 >= 0 && !visited[i][j - 1]){
            if (grid[i][j - 1] == 0){
                cur++;
                set.add(index(i, j - 1));
            }else{
                cur += dfs(grid, i, j - 1);
            }
        }
        if (j + 1 < m && !visited[i][j + 1]){
            if (grid[i][j + 1] == 0){
                cur++;
                set.add(index(i, j + 1));
            }else{
                cur += dfs(grid, i, j + 1);
            }
        }
        return cur;
    }

    private int index(int i, int j){
        return m * i + j;
    }
}
Published 1824 original articles · 30,000+ praises · 4.78 million views

Guess you like

Origin blog.csdn.net/a1439775520/article/details/105540556