LintCode第433题-岛屿的个数
描述
给一个 01 矩阵,求不同的岛屿的个数。
0 代表海,1 代表岛,如果两个 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
样例 2:
输入:
[[1,1]
]
输出:
1
思路:先判断用什么方法解题
规则的二维网格结构-有相邻规则-统计连通块,最短路径,区域面积等 访问一个点后要访问所有相邻且符合条件的点-本质是图的遍历
通常情况下 最短路径以及数据量非常大用BFS 只需要遍历连通块通常情况DFS就可以了
易错点:容易将条件判断为上下左右不是1才会计数-这只会数“孤岛像素”,和“岛屿个数”不是一回事
代码如下:
public class Solution {
// 上、下、左、右(顺序固定)
private static final int[] DR = {-1, 1, 0, 0};
private static final int[] DC = {0, 0, -1, 1};
/**
* @param grid: a boolean 2D matrix (true=陆地, false=海)
* @return: 岛屿数量
*/
public int numIslands(boolean[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;
int m = grid.length, n = grid[0].length;//因为这里的岛屿不为锯齿状即规则二维数组 所以可以用grid[0].length计算出来所有的列都为这个值
int count = 0;
for(int r=0;r<m;r++)
{
for(int c=0;c<n;c++)
{
if(grid[r][c])//首次遇见一个小岛
{
count++;
dfsSurroundIsland(grid,r,c);//去掉整块(标记为已访问 条件就是相邻的岛屿就是一整块)
}
}
}
return count;
}
private void dfsSurroundIsland(boolean[][] g, int r, int c)//消灭上下邻接重复的岛屿 这一片岛屿只算1次
{
//边界条件
int m = g.length, n = g[0].length;
if(r<0||r>=m||c<0||c>=n||!g[r][c])//g[r][c]表示 如果是海洋的话就停止了
{
return;
}else
{
g[r][c] = false//将当前格子标记为已访问 该句是关键句
}
for(int i=0;i<4;i++)
{
dfsSurroundIsland(g,r+DR[i],c+DC[i]);//分别代表上下左右 dr 表示行的变化量 即进行上下偏移 dc表示列的变化量 即进行左右偏移
}
}
}