《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。

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

  • 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,避免之前岛屿的面积干扰当前统计。

五、流程图

相关推荐
倒头就睡的小比特4 天前
算法竞赛C++常用的STL
c++·算法
weilx12344 天前
C++笔记-文件IO-<fcntl.h>
c++
小羊没烦恼!4 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼4 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
Smileyqp沛沛4 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车4 天前
C/C++ 为什么需要编译器?
开发语言·c++
旖旎夜光4 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark4 天前
大规模并行计算中的负载均衡算法研究4
算法
吞下星星的少年·-·4 天前
C++ 萌新语法入门篇
c++·算法比赛
Because_of_Her14 天前
并查集-听课笔记
笔记·算法·并查集