题见:岛屿数量
这题关键在于如何寻找并标记「岛屿」,这就要 DFS 算法发挥作用了
dfs的基本框架如下
// 方向数组,分别代表上、下、左、右
int[][] dirs = new int[][]{{-1,0}, {1,0}, {0,-1}, {0,1}};
void dfs(int[][] grid, int i, int j, boolean[] visited) {
int m = grid.length, n = grid[0].length;
if (i < 0 || j < 0 || i >= m || j >= n) {
// 超出索引边界
return;
}
if (visited[i][j]) {
// 已遍历过 (i, j)
return;
}
// 进入节点 (i, j)
visited[i][j] = true;
// 递归遍历上下左右的节点
for (int[] d : dirs) {
int next_i = i + d[0];
int next_j = j + d[1];
dfs(grid, next_i, next_j);
}
// 离开节点 (i, j)
// visited[i][j] = true;
}
但是这题我们可以简便一下,每次遇到岛屿就用dfs把岛屿淹没了,这样就可以避免使用观测数组来标记一个岛屿是否被观测过
int map[1000][1000] = { 0 };
int ret = 0;
int m, n;//行,列
void dfs(int i,int j)
{
if (i < 0 || j < 0 || i >= m || j >= n)//超出边界
return;
if (map[i][j] == 0)//已经是水
return;
map[i][j] = 0;//将陆地变成水
dfs(i - 1, j);//淹没上下左右的岛屿
dfs(i + 1, j);
dfs(i, j + 1);
dfs(i, j - 1);
}
int main()
{
cin >> m >> n;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> map[i][j];
}
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (map[i][j] == 1)//发现新岛屿ret++
{
dfs(i, j);
ret++;
}
}
}
cout << ret << endl;
return 0;
}