30-Day Leetcoding Challenge Day17(构造并查集)

很经典的一道题,提供三种解法:DFS,BFS,并查集

1.DFS遍历每个点,如果等于1,将其设置为0,递归遍历其周围的四个点(在矩阵范围内)。计算触发DFS结点的数目。

2.BFS遍历每个点,如果等于1,将其设置为0,用while循环加队列遍历其周围的点(在矩阵范围内),直到队列为空。计算触发BFS结点的数目。

3.并查集:构造了并查集

JAVA

class Solution {
    public void dfs(char[][] grid, int a, int b){
        grid[a][b] = '0';
        if(a-1 >= 0 && grid[a-1][b] == '1')dfs(grid, a-1, b);
        if(a+1 < grid.length && grid[a+1][b] == '1')dfs(grid, a+1, b);
        if(b-1 >= 0 && grid[a][b-1] == '1')dfs(grid, a, b-1);
        if(b+1 < grid[0].length && grid[a][b+1] == '1')dfs(grid, a, b+1);
    }
    public int numIslands(char[][] grid) {
        if(grid == null || grid.length == 0){
            return 0;
        }
        int m = grid.length;
        int n = grid[0].length;
        int res = 0;
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(grid[i][j] == '1'){
                    res++;
                    dfs(grid, i, j);
                }
            }
        }
        return res;
    }
}
class Solution {
    public int numIslands(char[][] grid) {
        if(grid == null || grid.length == 0){
            return 0;
        }
        int m = grid.length;
        int n = grid[0].length;
        int res = 0;
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(grid[i][j] == '1'){
                    res++;
                    grid[i][j] = '0';
                    Queue<Integer> queue = new LinkedList<>();
                    queue.add(i*n+j);//!!!对坐标的保存
                    while(!queue.isEmpty()){
                        int id = queue.remove();
                        int row = id / n;
                        int col = id % n;
                        if(row-1 >= 0 && grid[row-1][col] == '1'){
                            grid[row-1][col] = '0';
                            queue.add((row-1)*n + col);
                        }
                        if(row+1 < m && grid[row+1][col] == '1'){
                            grid[row+1][col] = '0';
                            queue.add((row+1)*n + col);
                        }
                        if(col-1 >= 0 && grid[row][col-1] == '1'){
                            grid[row][col-1] = '0';
                            queue.add(row*n + col-1);
                        }
                        if(col+1 < n && grid[row][col+1] == '1'){
                            grid[row][col+1] = '0';
                            queue.add(row*n + col+1);
                        }
                    }
                }
            }
        }
        return res;
    }
}
class Solution {
  class UnionFind {
    int count; // # of connected components
    int[] parent;
    int[] rank;

    public UnionFind(char[][] grid) { // for problem 200
      count = 0;
      int m = grid.length;
      int n = grid[0].length;
      parent = new int[m * n];
      rank = new int[m * n];
      for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
          if (grid[i][j] == '1') {
            parent[i * n + j] = i * n + j;
            ++count;
          }
          rank[i * n + j] = 0;
        }
      }
    }

    public int find(int i) { // path compression
      if (parent[i] != i) parent[i] = find(parent[i]);
      return parent[i];
    }

    public void union(int x, int y) { // union with rank
      int rootx = find(x);
      int rooty = find(y);
      if (rootx != rooty) {
        if (rank[rootx] > rank[rooty]) {
          parent[rooty] = rootx;
        } else if (rank[rootx] < rank[rooty]) {
          parent[rootx] = rooty;
        } else {
          parent[rooty] = rootx; rank[rootx] += 1;
        }
        --count;
      }
    }

    public int getCount() {
      return count;
    }
  }

  public int numIslands(char[][] grid) {
    if (grid == null || grid.length == 0) {
      return 0;
    }

    int nr = grid.length;
    int nc = grid[0].length;
    int num_islands = 0;
    UnionFind uf = new UnionFind(grid);
    for (int r = 0; r < nr; ++r) {
      for (int c = 0; c < nc; ++c) {
        if (grid[r][c] == '1') {
          grid[r][c] = '0';
          if (r - 1 >= 0 && grid[r-1][c] == '1') {
            uf.union(r * nc + c, (r-1) * nc + c);
          }
          if (r + 1 < nr && grid[r+1][c] == '1') {
            uf.union(r * nc + c, (r+1) * nc + c);
          }
          if (c - 1 >= 0 && grid[r][c-1] == '1') {
            uf.union(r * nc + c, r * nc + c - 1);
          }
          if (c + 1 < nc && grid[r][c+1] == '1') {
            uf.union(r * nc + c, r * nc + c + 1);
          }
        }
      }
    }

    return uf.getCount();
  }
}

Python3

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        if not grid or not grid[0]:
            return 0
        res = 0
        m = len(grid)
        n = len(grid[0])
        for x in range(m):
            for y in range(n):
                if grid[x][y] == '1':
                    self.dfs(grid, x, y)
                    res += 1
        return res
        
    def dfs(self, grid, a, b):
        grid[a][b] = '0'
        for i, j in [(a+1, b), (a-1, b), (a, b-1), (a, b+1)]:
            if 0 <= i < len(grid) and 0 <= j < len(grid[0]) and grid[i][j] == '1':
                self.dfs(grid, i, j)
class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        if not grid or not grid[0]:
            return 0
        res = 0
        m = len(grid)
        n = len(grid[0])
        for x in range(m):
            for y in range(n):
                if grid[x][y] == '1':
                    res += 1
                    queue = []
                    queue.append((x,y))
                    while queue:
                        row, col = queue.pop(0)
                        if row-1 >= 0 and grid[row-1][col] == '1':
                            grid[row-1][col] = '0'
                            queue.append((row-1,col))
                        if row+1 < m and grid[row+1][col] == '1':
                            grid[row+1][col] = '0'
                            queue.append((row+1,col))
                        if col-1 >= 0 and grid[row][col-1] == '1':
                            grid[row][col-1] = '0'
                            queue.append((row,col-1))
                        if col+1 < n and grid[row][col+1] == '1':
                            grid[row][col+1] = '0'
                            queue.append((row,col+1))
        return res
原文地址:https://www.cnblogs.com/yawenw/p/12798169.html