一.题目

二.思路讲解
2.1 思路讲解
本题与之前 FloodFill 系列的题目思路一致,都是通过深度优先搜索(DFS) 遍历连通区域。但有一个关键区别:不能回溯 。之前的回溯问题(如路径搜索)是在探索不同分支后需要恢复现场 ,而 FloodFill 是"一次性灌溉 "------每个格子一旦被访问就永久标记,无需撤销。这就像"弱水三千,只取一瓢 "的路径搜索需要尝试多种可能,而岛屿面积则是"我全都要",把整个连通区域一次性全部找出来,然后记录大小。
三.代码演示
cpp
class Solution {
public:
int ret = 0;
int row,col;
bool check[51][51];
int bx[4] = {0,0,1,-1};
int by[4] = {1,-1,0,0};
int count = 0;
int maxAreaOfIsland(vector<vector<int>>& grid)
{
row = grid.size(),col = grid[0].size();
for(int i = 0;i < row;i++)
{
for(int j = 0;j < col;j++)
{
if(grid[i][j] == 1 && !check[i][j])
{
count = 0;
dfs(grid,i,j);//把一开始的算上
ret = max(ret,count);
}
}
}
return ret;
}
void dfs(vector<vector<int>>& grid,int i,int j)
{
//必须提前,因为我一开始的起点也要设置
count++;
check[i][j] = true;
for(int k = 0;k < 4;k++)
{
int x = i + bx[k],y = j + by[k];
if(x >= 0 && y >= 0 && x < row && y < col && !check[x][y] && grid[x][y] == 1)
{
dfs(grid,x,y);
}
}
}
};
四.代码讲解
一、全局变量与数据结构
-
ret:整型变量,记录当前找到的最大岛屿面积,初始为 0。 -
row、col:成员变量,存储网格的行数和列数。 -
check[51][51]:布尔数组,记录每个格子是否已被访问过,避免重复遍历。大小 51 足以应对常见数据范围。 -
count:整型变量,记录当前正在遍历的岛屿的面积,在每次发现新岛屿时重置为 0。 -
方向数组
bx[4]、by[4]:表示上下左右四个方向的偏移量,用于探索相邻格子。
二、主函数 maxAreaOfIsland
-
获取网格的行数
row和列数col。 -
遍历整个网格,对于每个格子
(i, j):-
如果当前格子是陆地
1且未被访问过(!check[i][j]),则说明发现了一个新的岛屿。 -
将
count重置为 0,然后调用递归函数dfs从该格子开始进行深度优先搜索,统计整个岛屿的面积。 -
用当前岛屿面积
count更新全局最大值ret。
-
-
遍历结束后,返回最大岛屿面积
ret。
三、递归函数 dfs
dfs(grid, i, j) 的作用是:从当前格子 (i, j) 出发,向四个方向探索,将所有与之相连的陆地格子标记为已访问,并累加面积计数。执行流程如下:
1. 标记当前格子并计数
首先将当前格子标记为已访问(check[i][j] = true),并将面积计数器 count 加 1。这一步必须在递归入口处完成,确保当前格子被计入面积,且不会重复访问。
2. 向四个方向探索
使用 for 循环遍历四个方向,计算新坐标 (x, y)。对于每个方向,检查该格子是否合法:
-
边界检查 :
x >= 0 && y >= 0 && x < row && y < col。 -
未访问 :
!check[x][y]。 -
是陆地 :
grid[x][y] == 1。
如果条件满足,则递归调用 dfs(grid, x, y),继续深入探索。
四、关键细节
-
无需回溯 :FloodFill 与回溯不同,格子一旦被标记为已访问,就永久改变状态,不需要撤销。因此递归返回后无需恢复现场,
count会随着递归深入自然累加。 -
面积统计 :通过全局变量
count在递归过程中不断累加,每个陆地块只被计数一次,最终得到整个岛屿的面积。 -
主函数中的重置 :每发现一个新岛屿,就将
count重置为 0,避免之前岛屿的面积干扰当前统计。
五、流程图
