题目地址:
https://www.lintcode.com/problem/number-of-islands/description
给定一个boolean矩阵,标记为true的点代表陆地,标记为false的点代表海洋。问整个矩阵里有多少岛屿。可以用BFS来做,每遍历到一个true的时候,用BFS标记其与其周围的true都为false,同时统计岛屿个数。最后返回即可。代码如下:
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
/**
* @param grid: a boolean 2D matrix
* @return: an integer
*/
public int numIslands(boolean[][] grid) {
// write your code here
// 判空
if (grid == null || grid.length == 0 || grid[0].length == 0) {
return 0;
}
// 开个二维数组表示四个方向
int[][] d = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
// 如果遇到了陆地,就开始做标记,同时计一个岛屿
if (grid[i][j]) {
markByBFS(grid, i, j, d);
res++;
}
}
}
return res;
}
private void markByBFS(boolean[][] grid, int x, int y, int[][] d) {
// 先将起点标注为访问过
grid[x][y] = false;
// 为了BFS,开一个队列,储存本层访问的grid格点
Queue<int[]> queue = new LinkedList<>();
// 将起点入队
queue.offer(new int[]{x, y});
while (!queue.isEmpty()) {
int[] cur = queue.poll();
for (int i = 0; i < 4; i++) {
// 试着向一个方向走一步
int[] adj = {cur[0] + d[i][0], cur[1] + d[i][1]};
// 如果这一步到达的格点还在grid范围内,并且这个格点也是陆地,则将其入队并标记为访问过
if (0 <= adj[0] && adj[0] < grid.length
&& 0 <= adj[1] && adj[1] < grid[0].length && grid[adj[0]][adj[1]]) {
queue.offer(adj);
grid[adj[0]][adj[1]] = false;
}
}
}
}
}
时间复杂度 O ( n ) O(n) O(n), n n n为矩阵规模。