《LeetCode 695 岛屿的最大面积 FloodFill DFS 解法》

一.题目

695. 岛屿的最大面积 - 力扣(LeetCode)

二.思路讲解

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。

  • rowcol:成员变量,存储网格的行数和列数。

  • check[51][51]:布尔数组,记录每个格子是否已被访问过,避免重复遍历。大小 51 足以应对常见数据范围。

  • count:整型变量,记录当前正在遍历的岛屿的面积,在每次发现新岛屿时重置为 0。

  • 方向数组 bx[4]by[4]:表示上下左右四个方向的偏移量,用于探索相邻格子。

二、主函数 maxAreaOfIsland
  1. 获取网格的行数 row 和列数 col

  2. 遍历整个网格,对于每个格子 (i, j)

    • 如果当前格子是陆地 1 且未被访问过(!check[i][j]),则说明发现了一个新的岛屿。

    • count 重置为 0,然后调用递归函数 dfs 从该格子开始进行深度优先搜索,统计整个岛屿的面积。

    • 用当前岛屿面积 count 更新全局最大值 ret

  3. 遍历结束后,返回最大岛屿面积 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,避免之前岛屿的面积干扰当前统计。

五、流程图

相关推荐
Jerry10 小时前
LeetCode 707. 设计链表
算法
疋瓞10 小时前
python和C++对比(1)_数据类型和数据结构
数据结构·c++·python
C语言小火车11 小时前
C++ 堆排序深度精讲:基于完全二叉树的选择排序进化,最坏情况 O(n log n) 的稳定王者
开发语言·c++·算法·排序算法·堆排序
kebidaixu11 小时前
两轮BMS AFE SH367306 I2C 读写时序
算法
智能排队系统_头部供应商11 小时前
RK3588边缘网关改造银行排队系统实战
算法
Fabarta11 小时前
从 0 实现 ChatGPT 风格的流式对话 UI
算法·架构
手写码匠11 小时前
手写 AI 上下文压缩系统:从零实现 Prompt 压缩与选择性上下文管理
人工智能·深度学习·算法·aigc
ALex_zry11 小时前
C++26 std::complex 结构化绑定详解:auto [re, im] = c
c语言·开发语言·c++
EAI-Robotics12 小时前
机器人操作鲁棒性:当机械手遇上真实世界的不确定性
人工智能·算法·机器人
Tairitsu_H13 小时前
[LC优选算法#17] 链表 | 合并 K 个升序链表 | K个⼀组翻转链表
数据结构·算法·链表