描述
给一个01矩阵,求不同的岛屿的个数。
0代表海,1代表岛,如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。
样例
在矩阵
[
[1, 1, 0, 0, 0],
[0, 1, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1]
]
有3个岛
代码
- BFS
class Coordinate {
int x, y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Solution {
/**
* @param grid a boolean 2D matrix
* @return an integer
*/
public int numIslands(boolean[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) {
return 0;
}
int m = grid.length;
int n = grid[0].length;
int islands = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j]) {
// 当点是1时才执行markedByBST,所以markedByBST算法具体实现时不需要再判断grid[i][j]对应的布尔值
markedByBST(grid, i, j);
islands++;
}
}
}
return islands;
}
// 用BFS寻找1点周围四个点,然后将找到的1点标记false
private void markedByBST(boolean[][] grid, int x, int y) {
int[] detalX = {0, 0, 1, -1};
int[] detalY = {1, -1, 0, 0};
Queue<Coordinate> queue = new LinkedList<>();
queue.offer(new Coordinate(x, y));
grid[x][y] = false;
while (!queue.isEmpty()) {
Coordinate coor = queue.poll();
for (int i = 0; i < 4; i++) {
Coordinate head = new Coordinate(coor.x + detalX[i], coor.y + detalY[i]);
if (!inBound(grid, head.x, head.y)) {
continue;
}
if (grid[head.x][head.y]) {
grid[head.x][head.y] = false;
queue.offer(head);
}
}
}
}
private boolean inBound(boolean[][] grid, int x, int y) {
int m = grid.length;
int n = grid[0].length;
return x >= 0 && x < m && y >= 0 && y < n;
}
}
- Union Find
class UnionFind {
private int[] father = null;
private int count;
private int find(int x) {
if (father[x] == x) {
return x;
}
return father[x] = find(father[x]);
}
public UnionFind(int n) {
// initialize your data structure here.
father = new int[n];
for (int i = 0; i < n; ++i) {
father[i] = i;
}
}
public void connect(int a, int b) {
int root_a = find(a);
int root_b = find(b);
if (root_a != root_b) {
father[root_a] = root_b;
count --;
}
}
public int query() {
return count;
}
public void set_count(int total) {
count = total;
}
}
public class Solution {
/**
* @param grid a boolean 2D matrix
* @return an integer
*/
public int numIslands(boolean[][] grid) {
int count = 0;
int n = grid.length;
if (n == 0)
return 0;
int m = grid[0].length;
if (m == 0)
return 0;
UnionFind union_find = new UnionFind(n * m);
int total = 0;
for(int i = 0;i < grid.length; ++i)
for(int j = 0;j < grid[0].length; ++j)
if (grid[i][j])
total ++;
union_find.set_count(total);
for(int i = 0;i < grid.length; ++i)
for(int j = 0;j < grid[0].length; ++j)
if (grid[i][j]) {
if (i > 0 && grid[i - 1][j]) {
union_find.connect(i * m + j, (i - 1) * m + j);
}
if (i < n - 1 && grid[i + 1][j]) {
union_find.connect(i * m + j, (i + 1) * m + j);
}
if (j > 0 && grid[i][j - 1]) {
union_find.connect(i * m + j, i * m + j - 1);
}
if (j < m - 1 && grid[i][j + 1]) {
union_find.connect(i * m + j, i * m + j + 1);
}
}
return union_find.query();
}
}
- DFS (not recommended)
public class Solution {
/**
* @param grid a boolean 2D matrix
* @return an integer
*/
private int m, n;
public void dfs(boolean[][] grid, int i, int j) {
if (i < 0 || i >= m || j < 0 || j >= n) return;
if (grid[i][j]) {
grid[i][j] = false;
dfs(grid, i - 1, j);
dfs(grid, i + 1, j);
dfs(grid, i, j - 1);
dfs(grid, i, j + 1);
}
}
public int numIslands(boolean[][] grid) {
// Write your code here
m = grid.length;
if (m == 0) return 0;
n = grid[0].length;
if (n == 0) return 0;
int ans = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (!grid[i][j]) continue;
ans++;
dfs(grid, i, j);
}
}
return ans;
}
}