题目
给你一个由 '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--;
}
}
}