岛屿数量
给你一个由 '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(); } }
|