#LC695. 岛屿的最大面积
岛屿的最大面积
你好!作为金牌教练,我们已经完成了“统计岛屿个数”、“判断封闭岛屿”、“计算飞地像素”的专项训练。今天,我们要挑战岛屿系列的第四个维度:“岛屿的最大面积”。
这道题在逻辑上要求我们在搜索的过程中,不仅要“走到”,还要“带回信息”。这是从单纯的连通性搜索向连通块属性维护的进阶。
一、 题目描述:岛屿的最大面积 (Max Area of Island)
题目背景: 在海洋地理信息系统中,我们需要找出面积最大的岛屿以建立科研基地。
任务描述:
给你一个大小为 的二进制矩阵 grid 。
- 岛屿是由一些相邻的
1(代表土地) 构成的组合,这里的“相邻”要求两个1必须在水平或者垂直方向上相邻。 - 你可以假设
grid的四个边缘都被0(代表水) 包围着。 - 岛屿的面积是该岛屿中具有土地条件的单元格数目。
- 请计算并返回
grid中最大的岛屿面积。如果没有岛屿,则返回面积为0。
输入格式:
第一行包含两个整数 和 ,。
接下来的 行,每行包含 个用空格分隔的整数(0 或 1)。
输出格式: 输出一个整数,表示最大的岛屿面积。
样例 1:
输入:
8 13
0 0 1 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 0 0 0
0 1 1 0 1 0 0 0 0 0 0 0 0
0 1 0 0 1 1 0 0 1 0 1 0 0
0 1 0 0 1 1 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1 1 1 0 0 0
0 0 0 0 0 0 0 1 1 0 0 0 0
输出:
6
样例 2:
输入:
1 1
0
输出:
0
二、 预备知识点
- 深度优先搜索 (DFS) 的返回值: 理解如何通过递归函数返回当前子树/连通块的大小。
- 全局最优解维护: 在遍历过程中不断更新
max_ans。 - 隐式图遍历: 依然是网格图的四连通模型。
- 状态重置 (访问标记): 确保每个陆地单位只被计算一次。
三、 启发式引导:将思路写在草稿纸上
请在纸上画一个小型的 陆地块,跟着我的步骤操作:
1. 核心逻辑:带信息的“回声”
- 单纯搜索(前几课): 只要走到新格子,就把它染成 0。
- 计算面积(本课):
- 当你站在格子 时,你问周围四个邻居:“你们那边相连的陆地一共有多少个?”
- 邻居回答后,你把他们的结果加起来,再加上你自己(1个)。
- 这就是典型的递归:
return 1 + dfs(上) + dfs(下) + dfs(左) + dfs(右);
2. 时间与空间复杂度分析
- 时间复杂度: 每个格子依然只被访问一次。。
- 空间复杂度: 递归深度。。对于 的规模,完全不需要担心栈溢出。
3. 优化建议
- 原地修改: 访问过的
1立即改为0,避免使用visited数组增加空间开销。 - 边界提前剪枝: 在调用递归前检查坐标合法性。
四、 算法流程图 (Mermaid 风格)
请注意,在 NOI 风格中,我们通常将 dfs 定义为一个返回 int 的函数:
graph TD
Start("开始") --> InitAns("初始化 max_area 等于 0")
InitAns --> LoopI("遍历行 i 从 0 到 M-1")
LoopI --> LoopJ("遍历列 j 从 0 到 N-1")
LoopJ --> Check1{"grid_i_j 是 1 吗?"}
Check1 -- "是" --> CallDFS("调用 dfs_function 统计当前岛屿面积")
CallDFS --> UpdateMax("max_area 等于 max_area 与 current_area 的较大值")
UpdateMax --> LoopJNext("检查下一个格子")
Check1 -- "否" --> LoopJNext
subgraph DFS_Function
D1("当前格子标记为 0") --> D2("初始化 count 等于 1")
D2 --> D3("递归获取上下左右四个方向的面积和")
D3 --> D4("返回 count 加 累计面积")
end
LoopJNext --> EndJ{"列遍历结束?"}
EndJ -- "否" --> LoopJ
EndJ -- "是" --> EndI{"行遍历结束?"}
EndI -- "否" --> LoopI
EndI -- "是" --> Output("输出 max_area")
五、 读题理解关键词
在 NOI 竞赛读题时,如何敏锐捕捉本题与其他岛屿题的区别?
- “最大” (Max):
- 这是一个典型的极值问题。
- 策略: 需要一个全局变量来记录过程中的最大值,每次 DFS 结束后进行比对。
- “单元格数目” (Number of units):
- 确定了度量标准:面积 = 格子的个数。
- 策略: DFS 必须有返回值,或者在 DFS 内部累加一个计数器。
- “水平或垂直” (Horizontal or Vertical):
- 再次确认是四连通。如果是八连通,面积计算会完全不同。
- 数据范围 (50):
- 这是一个非常友好的范围。即使你的递归写得不够精炼,或者使用了较多的辅助空间,也很难超时。这意味着你可以更关注代码的准确性。
教练点评: “岛屿的最大面积”是搜索算法中“信息回传”的敲门砖。当你习惯了让递归函数带回一个数字(面积)而不是简单的布尔值(是否连通)时,你就已经半只脚踏进了树形 DP 或者更高级搜索剪枝的大门。加油!