【递归、搜索与回溯】FloodFill算法(一)

📝前言说明:

  • 本专栏主要记录本人递归,搜索与回溯算法的学习以及LeetCode刷题记录,按专题划分
  • 每题主要记录:(1)本人解法 + 本人屎山代码;(2)优质解法 + 优质代码;(3)精益求精,更好的解法和独特的思想(如果有的话)
  • 文章中的理解仅为个人理解。如有错误,感谢纠错

🎬个人简介:努力学习ing

📋本专栏:C++刷题专栏

📋其他专栏:C语言入门基础,python入门基础,C++学习笔记,Linux

🎀CSDN主页 愚润泽

你可以点击下方链接,进行该专题内不同子专题的学习

点击链接 开始学习
导论 递归 (一) 、递归 (二)
二叉树的深搜 穷举 vs 暴搜 vs 深搜 vs 回溯 vs 剪枝
综合练习(一) 综合练习(二)
综合练习(三) 综合练习(四)
FloodFill(一) FloodFill(二)
记忆化搜索(一) 记忆化搜索(二)

题单汇总链接:点击 → 题单汇总

题目

  • [FloodFill 算法介绍](#FloodFill 算法介绍)
  • [733. 图像渲染](#733. 图像渲染)
  • [200. 岛屿数量](#200. 岛屿数量)
  • [695. 岛屿的最大面积](#695. 岛屿的最大面积)

FloodFill 算法介绍

  • 找性质相同(比如同为负数...)的连通块,连通是指:上下左右直接相连的,斜的不算
  • 解法:可用dfs / bfs来遍历(本专题讨论 dfs)

733. 图像渲染

题目链接:https://leetcode.cn/problems/flood-fill/description/

个人解

思路:

  • 深度优先,往四个方向尝试
  • 特别要注意无限递归问题

用时:10:00

屎山代码:

cpp 复制代码
class Solution {
public:
    int base;
    int m, n;
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    void dfs(vector<vector<int>>& image, int row, int col, int color)
    {
        for(int i = 0; i < 4; i++) // 遍历四个方向
        {
            int r = row + dx[i], l = col + dy[i];
            if(r < m && r >= 0 && l < n && l >= 0 && image[r][l] == base)
            {
                image[r][l] = color;
                dfs(image, r, l, color);
            }
        }
    }
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) 
    {
        base = image[sr][sc]; // 初始像素的原始颜色
        // 目标颜色和初始颜色相同直接返回(不然可能在几块区间反复调 dfs 无限递归)
        if(base == color) return image; 
        m = image.size(); n = image[0].size();
        image[sr][sc] = color;
        dfs(image, sr, sc, color);
        return image;
    }
};

时间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)
空间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)


200. 岛屿数量

题目链接:https://leetcode.cn/problems/number-of-islands/description/

个人解

思路:

  • dfs不多说了
  • 有一个很妙的地方,可以不用check数组:没走过一个为1的地方就把它变成0

用时:16:00

屎山代码:

cpp 复制代码
class Solution {
public:
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
    int ans = 0;
    int m, n;
    void dfs(vector<vector<char>>& grid, int row, int col)
    {
        if(grid[row][col] == '1')
        {
            grid[row][col] = '0'; // 置为 0 
            for(int i = 0; i < 4; i++)
            {
                int r = row + dx[i], c = col + dy[i]; // 下一个位置
                if(r < m && r >= 0 && c < n && c >= 0)
                    dfs(grid, r, c);
            }
        }
    }
    int numIslands(vector<vector<char>>& grid) 
    {
        m = grid.size(); n = grid[0].size();
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(grid[i][j] == '0')
                    continue;
                else
                {
                    dfs(grid, i, j); // 调用一次就会把一整块陆地找到
                    ans++;  // 记录总 dfs 次数
                }
            }
        }
        return ans;
    }
};

时间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)
空间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)


695. 岛屿的最大面积

题目链接:https://leetcode.cn/problems/max-area-of-island/description/

个人解

思路:

  • 一样的方法,只是要注意,答案的更新放在dfs外面(用一个全局变量来记录每次dfs的面积,然后下一次dfs前重新置为0)

用时:6:00

屎山代码:

cpp 复制代码
class Solution {
public:
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
    int ans = 0;
    int s = 0;
    int m, n;
    void dfs(vector<vector<int>>& grid, int row, int col) // s 记录面积
    {
        if(grid[row][col] == 1)
        {
            s++;
            grid[row][col] = 0; // 置为 0
            for(int i = 0; i < 4; i++)
            {
                int r = row + dx[i], c = col + dy[i]; // 下一个位置
                if(r < m && r >= 0 && c < n && c >= 0)
                    dfs(grid, r, c);
            }
        }
    }

    int maxAreaOfIsland(vector<vector<int>>& grid) {
        m = grid.size(); n = grid[0].size();
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(grid[i][j] == 0)
                    continue;
                else
                {
                    dfs(grid, i, j);
                    ans = max(ans, s);
                    s = 0;
                }
            }
        }
        return ans;
    }
};

时间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)
空间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)


🌈我的分享也就到此结束啦🌈

要是我的分享也能对你的学习起到帮助,那简直是太酷啦!

若有不足,还请大家多多指正,我们一起学习交流!

📢公主,王子:点赞👍→收藏⭐→关注🔍

感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

相关推荐
草莓熊Lotso4 小时前
【C++ 基于微服务的即时通讯系统】etcd + brpc 从安装到服务注册发现全链路实战
网络·数据库·c++·redis·微服务·etcd
HPtiger10 小时前
数据结构——选择排序
数据结构·算法·排序算法
康实训10 小时前
老年评估仿真实训平台架构设计与老年人能力评估实训室教学落地实践
大数据·人工智能·算法·实训室·实训室建设
DongQiShanRen10 小时前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习
CCblandy10 小时前
雪花 ID 四个边界实测:时钟回拨重号 500 个,前端 JSON.parse 直接丢精度
后端·python·算法·性能优化·架构
丑梨数据11 小时前
信创环境里跑文档工具:格式兼容与本地合规的几个坑
数据结构·人工智能·算法·决策树·排序算法
把我格子衫拿来11 小时前
VTK 9.5 与 Qt 6 联合开发:从嵌入三维窗口到可维护的桌面架构
c++·python·qt·vtk·三维可视化
无忧.芙桃11 小时前
C++语言原理与实践(十六):多态机制讲解
开发语言·c++·多态
erzong23112 小时前
Linux操作系统:线程概念与控制
linux·算法
wuminyu13 小时前
JMM学习总结:深入理解happens-before关系
java·linux·c语言·jvm·c++