695. 岛屿的最大面积(Max Area of Island)
难度:中等 | 主题:图论、DFS、BFS
题目
给你一个大小为 m x n 的二进制矩阵 grid。岛屿是由一些相邻的 1(代表陆地)构成的组合。这里的相邻要求两个单元格必须在水平或竖直方向上相邻。你可以假设 grid 的四个边缘都被水包围。求岛屿的最大面积。
示例
输入:grid = [[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
思路
先讲个故事:航拍数最大岛屿
你是卫星地图分析师,这次不是数岛屿数量,而是找最大的那个岛屿。
规则:相邻的陆地算同一个岛屿(上下左右连通)。
怎么找?在 200 题的基础上改:DFS 时返回岛屿面积(连通的 ‘1’ 的数量),取全局最大值。
引导式推导:200 的面积升级
核心改动: DFS 返回当前连通块的面积。
def dfs(i, j):
if 越界 or 不是陆地:
return 0
grid[i][j] = 0 # 沉岛
return 1 + dfs(i-1,j) + dfs(i+1,j) + dfs(i,j-1) + dfs(i,j+1)
对比 200 题:
| 维度 | 200 岛屿数量 | 695 岛屿最大面积 |
|---|---|---|
| DFS 返回值 | 无(void) | 面积(int) |
| 计数方式 | 遇到 ‘1’ 就 count++ | DFS 返回 1 + 四方向面积 |
| 最终结果 | count | max(count) |
代码
class Solution:
def maxAreaOfIsland(self, grid: list[list[int]]) -> int:
if not grid or not grid[0]:
return 0
m, n = len(grid), len(grid[0])
max_area = 0
def dfs(i: int, j: int) -> int:
if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] == 0:
return 0
grid[i][j] = 0
return 1 + dfs(i + 1, j) + dfs(i - 1, j) + dfs(i, j + 1) + dfs(i, j - 1)
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
max_area = max(max_area, dfs(i, j))
return max_area
复杂度
| 指标 | 值 | 解释 |
|---|---|---|
| 时间 | O(m*n) | 每个格子访问一次 |
| 空间 | O(m*n) | DFS 递归栈最坏情况 |
实战考量
频率分析
出现在:字节/美团 一面图论题,约 25% 常会考到。200 题的简单变形。
延伸思考
Q:如果要求最大岛屿的周长呢?
A:DFS 时统计边界数量,找边界的边数。
Q:如果要求所有岛屿的总面积呢?
A:累加每个连通块的面积。
Q:能不能不用修改原数组?
A:可以用 visited 数组,但空间多 O(m*n)。
Q:如果 grid 很大怎么办?
A:DFS 可能栈溢出,改用 BFS。
易错点
-
DFS 返回面积,注意边界返回 0
-
max_area 更新时机(DFS 返回后立即更新)
-
沉岛标记
grid[i][j] = 0
生活类比
航拍数最大岛屿
卫星地图分析师这次要找最大的岛屿。
看到一个 ‘1’,就派探测器沉掉整个岛屿,同时数面积。
沉了几个岛屿,记下每个的面积,取最大的。
沉岛 + 计面积 = 200 题的面积升级版。
相关题目
| 题目 | 关系 |
|---|---|
| 200岛屿数量 | 连通块计数基础 |
| 130被围绕的区域 | 多边界扩散 |
| 417太平洋大西洋水流问题 | 多源扩散 |
| 695岛屿的最大面积 | 本题 |
→ 返回题单:LeetCode学习路线图 > 十二、图论
速记卡(面试闪卡)
Q1:一句话讲清「695. 岛屿的最大面积(Max Area of Island)」到底是什么?
A:DFS/BFS 数出二进制矩阵里最大那块连通陆地(1)的面积。
Q2:题目 —— 怎么理解?
A:像航拍找大岛:给 m×n 的 0/1 矩阵,上下左右相邻的 1 算同一岛屿,四个边被水围。求所有岛屿里面积最大的那个。示例输出 6。
Q3:思路 —— 怎么理解?
A:像 200 题升级:DFS 时返回连通块面积而不是只计数。遇到 1 就沉岛(grid[i][j]=0)并 return 1 + 上下左右四个方向 DFS 之和;遍历全图对每个 1 调 DFS,用 max 取最大。visited 可用沉岛代替省空间。
Q4:代码 —— 怎么理解?
A:双重循环扫每个格子,遇到 1 就 dfs 更新 max_area。dfs:越界或遇 0 返回 0;否则沉岛并返回 1 + dfs(上下左右)。 grid 大怕栈溢出可改 BFS。
Q5:复杂度 —— 怎么理解?
A:像每格看一眼:时间 O(mn) 每个格子最多访问一次;空间 O(mn) DFS 递归栈最坏情况(整张图都是陆地)。
Q6:核心速记主线有哪些?
-
DFS 返回连通块面积,沉岛 grid[i][j]=0 防重复
-
是 200 岛屿数量的计数升级版(void→int,count→max)
-
求最大周长/总面积只需微调 DFS 统计
-
时间 O(mn)、空间 O(mn);图大改 BFS 防栈溢出
口诀
A:最大岛屿用深搜,
遇到陆地就沉掉;
四面面积加起来,
取个最大就报到。