200. 岛屿数量[中等]

146 阅读1分钟

题目

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

  • 来源:力扣(LeetCode)
  • 链接:leetcode-cn.com/problems/nu…
  • 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

DFS(depth first search)

    // DFS
    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }
        int result = 0;
        int row = grid.length;
        int col = grid[0].length;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == '1') {
                    result++;
                    dfs(grid, i, j, row, col);
                }
            }
        }
        return result;
    }
    
    private void dfs(char[][] grid, int x, int y, int row, int col) {
        if (x < 0 || y < 0 || x >= row || y >= col || grid[x][y] == '0') {
            return;
        }
        grid[x][y] = '0';
        dfs(grid, x - 1, y, row, col);
        dfs(grid, x + 1, y, row, col);
        dfs(grid, x, y - 1, row, col);
        dfs(grid, x, y + 1, row, col);
    }

BFS(breadth first search)

    // BFS
    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }
        int result = 0;
        int row = grid.length;
        int col = grid[0].length;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == '1') {
                    result++;
                    bfs(grid, i, j, row, col);
                }
            }
        }
        return result;
    }
    private void bfs(char[][] grid, int x, int y, int row, int col) {
        Queue<int []> queue = new LinkedList<>();
        queue.offer(new int[] {x, y});
        while (!queue.isEmpty()) {
            int[] index = queue.poll();
            x = index[0];
            y = index[1];
            if (x >= 0 && x < row && y >= 0 && y < col && grid[x][y] == '1') {
                grid[x][y] = '0';
                queue.offer(new int[] {x-1, y});
                queue.offer(new int[] {x+1, y});
                queue.offer(new int[] {x, y-1});
                queue.offer(new int[] {x, y+1});
            }
        }
    }

union find

    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }
        UnionFind unionFind = new UnionFind(grid);
        int waters = 0;
        int row = grid.length;
        int col = grid[0].length;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == '0') {
                    waters++;
                } else {
                    int[][] directions = new int[][] {{-1, 0}, {1, 0},  {0, -1}, {0, 1}};
                    for (int[] direction : directions) {
                        int x = i +direction[0];
                        int y = j + direction[1];
                        if (x >= 0 && x < row && y >= 0 && y < col && grid[x][y] == '1') {
                            unionFind.union(i * col + j, x * col + y);
                        }
                    }
                }
            }
        }
        return unionFind.count - waters;
    }

    private static class UnionFind {
        private int count;
        private int[] root;

        UnionFind(char[][] grid) {
            int row = grid.length;
            int col = grid[0].length;
            count = row * col;
            root = new int[row * col];
            for (int i = 0; i < row * col; i++) {
                root[i] = i;
            }
        }

        public int find(int x) {
            if (root[x] == x) {
                return root[x];
            } else {
                return find(root[x]);
            }
        }

        public void union(int x, int y) {
            int xRoot = find(x);
            int yRoot = find(y);
            if (xRoot != yRoot) {
                root[yRoot] = xRoot;
                count--;
            }
        }
    }

参考