岛屿数量 给你一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
1 2 3 4 5 6 7 输入:grid = [ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0","0","0","0","0"] ] 输出:1
示例 2:
1 2 3 4 5 6 7 输入:grid = [ ["1","1","0","0","0"], ["1","1","0","0","0"], ["0","0","1","0","0"], ["0","0","0","1","1"] ] 输出:3
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j]
的值为 '0'
或 '1'
并查集适用于动态连通性问题
对于这道题,并查集的思路如下:
初始化并查集
每个 '1'
(陆地)看作一个独立的集合(岛屿)。
每个 '1'
的 id
用 i * n + j
计算(展平成 1D 索引)。
初始时,每个 '1'
自己是自己的根 。
合并相邻的 '1'
遍历 grid
,当遇到 '1'
时,检查右边和下边 是否也是 '1'
。
如果是,就把它们合并 (Union 操作)。
统计连通分量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 class Solution { class UnionFind { int [] parent; int count = 0 ; public UnionFind (char [][] grid) { int m = grid.length; int n = grid[0 ].length; parent = new int [m * n]; for (int i = 0 ; i < m; i++) { for (int j = 0 ; j < n; j++) { if (grid[i][j] == '1' ) { count++; int id = i * n + j; parent[id] = id; } } } } private void union (int p, int q) { if (find(p) != find(q)) { int rootP = find(p); int rootQ = find(q); parent[rootP] = rootQ; count--; } } private int find (int p) { if (parent[p] != p) { parent[p] = find(parent[p]); } return parent[p]; } private int getCount () { return count; } } public int numIslands (char [][] grid) { int m = grid.length; int n = grid[0 ].length; int [] dx = new int [] { 0 , 1 , 0 , -1 }; int [] dy = new int [] { 1 , 0 , -1 , 0 }; UnionFind uf = new UnionFind (grid); for (int i = 0 ; i < m; i++) { for (int j = 0 ; j < n; j++) { if (grid[i][j] == '1' ) { for (int d = 0 ; d < 4 ; d++) { int x = i + dx[d]; int y = j + dy[d]; if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1' ) { uf.union(i * n + j, x * n + y); } } } } } return uf.getCount(); } }
还可以用DFS
来做。对网格进行遍历,如果该网格是陆地,岛屿数量+1
,对该网格进行深搜,把四周相连的陆地都标记为2
。当遍历完整个网格就得到了答案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Solution { char [][] grid; int m; int n; public int numIslands (char [][] grid) { this .grid = grid; this .m = grid.length; this .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(i, j); } } } return res; } private void dfs (int i, int j) { if (!isValaid(i, j)) { return ; } grid[i][j] = '2' ; dfs(i - 1 , j); dfs(i, j + 1 ); dfs(i + 1 , j); dfs(i, j - 1 ); } private boolean isValaid (int i, int j) { if (i < 0 || i >= m || j < 0 || j >= n) { return false ; } if (grid[i][j] != '1' ) { return false ; } return true ; } }