岛屿数量

给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

示例 1:

输入:

11110

11010

11000

00000

输出: 1

 

示例 2:

输入:

11000

11000

00100

00011

输出: 3

代码1  bfs

public static void main(String[] args) {
        char[][] grid = {
  {'1','1','1','1','0'},{'1','1','0','1','0'},{'1','1','0','0','0'},{'0','0','0','0','0'}};
        System.out.println(numIslands(grid));
    }
    public static int numIslands(char[][] grid) {
        // corner case
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }
        int[][] dirs = {
  {-1, 0}, {1, 0}, {0, -1}, {0, 1}};

        int count = 0;
        int rows = grid.length;
        int cols = grid[0].length;

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (grid[i][j] == '1') {
                    count++;
                    LinkedList<int []> queue = new LinkedList<>();
                    queue.add(new int[]{i, j});
                    while (!queue.isEmpty()) {
                        int[] cur = queue.poll();
                        for (int[] dir : dirs) {
                            int x = cur[0] + dir[0];
                            int y = cur[1] + dir[1];
                            if(x >= 0 && x < rows && y >= 0 && y < cols && grid[x][y] =='1'){
                                grid[x][y] = '0';
                                queue.add(new int[]{x, y});
                            }
                        }
                    }
                }
            }
        }
        return count;
    }
}

改版代码

public class Coordinate {
    int x,y;
    public Coordinate(int x,int y){
        this.x = x;
        this.y = y;
    }
}
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

/**
 * @Auther: liuhaidong
 * Data: 2019/10/14 0014、16:32
 * Description:
 * @version: 1.0
 */
public class numIslands {
    public static void main(String[] args) {
        char[][] grid = {
  {1,1,1,1,0},{1,1,0,1,0},{1,1,0,0,0},{0,0,0,0,0}};
        System.out.println(numIslands(grid));
    }
    public static int numIslands(char[][] grid) {
        if(grid ==null || grid.length ==0 || grid[0].length ==0){
            return 0;
        }
        int islands =0;
        for(int i =0;i<grid.length;i++){
            for(int j =0;j<grid[0].length;j++){
                if(grid[i][j] == '1'){
                    bfs(grid,i,j);
                    islands++;
                }
            }
        }
        return islands;
    }
    private static void bfs(char[][] grid,int x,int y){
        int[] diX ={0,0,1,-1};
        int[] diY ={1,-1,0,0};
        //确认走的四个方向
        Queue<Coordinate> queue = new LinkedList<>();
        queue.offer(new Coordinate(x,y));
        grid[x][y] = '0';
        while (!queue.isEmpty()){
            Coordinate coordinate = queue.poll();
            for (int i = 0; i < 4; i++) {
                Coordinate abj = new Coordinate(coordinate.x+diX[i],coordinate.y+diY[i]);
                if(!inBound(abj,grid)){
                    continue;
                }
                if(grid[abj.x][abj.y] == '1'){
                    grid[abj.x][abj.y] = '0';
                    queue.offer(abj);
                }
            }
        }
    }

    private static boolean inBound(Coordinate coor, char[][] grid) {
        int n = grid.length;
        int m = grid[0].length;
        return coor.x >= 0 && coor.x <n && coor.y >=0 && coor.y <m;
    }
}

代码2      dfs

public class Main {

    public static void main(String[] args) {
        char[][] grid = {
  {1,1,1,1,0},{1,1,0,1,0},{1,1,0,0,0},{0,0,0,0,0}};
        System.out.println(numIslands(grid));
    }

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

        int m = grid.length;
        int n = grid[0].length;
        int num_islands = 0;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == '1') {
                    ++num_islands;
                    dfs(grid, i, j);
                }
            }
        }

        return num_islands;
    }

    public static void dfs(char[][] grid, int x, int y) {
        int m = grid.length;
        int n = grid[0].length;

        if (x < 0 || y < 0 || x >= m || y >= n || grid[x][y] == '0') {
            return;
        }

        grid[x][y] = '0';
        dfs(grid, x - 1, y);
        dfs(grid, x + 1, y);
        dfs(grid, x, y - 1);
        dfs(grid, x, y + 1);
    }
}

代码3 并查集

public static void main(String[] args) {
    char[][] grid = {
  {'1','1','1','1','0'},{'1','1','0','1','0'},{'1','1','0','0','0'},{'0','0','0','0','0'}};
    System.out.println(numIslands(grid));
}
public static int numIslands(char[][] grid) {
    if (grid == null || grid.length == 0) {
        return 0;
    }
    int x = grid.length;
    int y = grid[0].length;
    int num_islands = 0;
    UnionFind uf = new UnionFind(grid);
    for (int i = 0; i < x; ++i) {
        for (int j = 0; j < y; ++j) {
            if (grid[i][j] == '1') {
                grid[i][j] = '0';
                if (i - 1 >= 0 && grid[i-1][j] == '1') {
                    uf.union(i * y + j, (i-1) * y + j);
                }
                if (i + 1 < x && grid[i+1][j] == '1') {
                    uf.union(i * y + j, (i+1) * y + j);
                }
                if (j - 1 >= 0 && grid[i][j-1] == '1') {
                    uf.union(i * y + j, i * y + j - 1);
                }
                if (j + 1 < y && grid[i][j+1] == '1') {
                    uf.union(i * y + j, i * y + j + 1);
                }
            }
        }
    }

    return uf.getCount();
}
public class UnionFind {
    int count;
    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) {
        if (parent[i] != i){
            parent[i] = find(parent[i]);
        }
        return parent[i];
    }

    public void union(int x, int y) {
        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;
    }
}