DFS:floodfill算法解决矩阵联通块问题

 floodfill,翻译为洪水灌溉,而floodfill算法本质上是为了解决在矩阵中性质相同的联通块问题。

一、图像渲染

. - 力扣(LeetCode)

class Solution {
public:
   int dx[4]={0,0,1,-1};
   int dy[4]={1,-1,0,0};
   int prev;//记住初始值
   int m,n;
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) 
    {
       //先考虑边界条件,如果对应位置和color是一样的,那么直接返回
       if(image[sr][sc]==color) return image;
       m=image.size(),n=image[0].size();
       prev=image[sr][sc];
       dfs(image,sr,sc,color); 
       return image;
    }

    void dfs(vector<vector<int>>& image, int i, int j, int color) //直接用引用,在矩阵上修改
    {
       //第一步,将当前位置修改成color
       image[i][j]=color;
       //第二步,用向量定义四个方向,然后去找
       for(int k=0;k<4;++k)
       {
        int x=i+dx[k],y=j+dy[k];
        if(x>=0&&x<m&&y>=0&&y<n&&image[x][y]==prev)
            dfs(image,x,y,color);
       }
    }
};

 二、岛屿问题

. - 力扣(LeetCode)

class Solution {
public:
    int ret=0;
    bool check[300][300];
    int m,n;
    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(!check[i][j]&&grid[i][j]=='1')//该数没被选过并且为1
          {
            ++ret;//说明找到一块岛屿
            dfs(grid,i,j);//然后让dfs去相邻位置将对应的子块给标记成true
          } 
         }
         return ret;
    }
   int dx[4]={0,0,1,-1};
   int dy[4]={1,-1,0,0};
    void dfs(vector<vector<char>>& grid,int i,int j)
    {
        //首先先把当前位置标记成选过
        check[i][j]=true;
        //然后通过向量去其他位置找
        for(int k=0;k<4;++k)
        {
            int x=i+dx[k],y=j+dy[k];
            if(x>=0&&x<m&&y>=0&&y<n&&!check[x][y]&&grid[x][y]=='1')
               dfs(grid,x,y);//继续去下一个位置找
        }
    }
};

三、岛屿的最大面积

. - 力扣(LeetCode)

class Solution {
public:
    bool check[50][50];
    int m,n;
    int count;//数每个字块的岛屿数量
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    int maxAreaOfIsland(vector<vector<int>>& grid) 
    {
       m=grid.size(),n=grid[0].size();
       int ret=0;
       for(int i=0;i<m;++i)
         for(int j=0;j<n;++j)
            if(!check[i][j]&&grid[i][j]==1)
              {
                 count=0;//重置count
                 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+dx[k],y=j+dy[k];
            if(x>=0&&x<m&&y>=0&&y<n&&!check[x][y]&&grid[x][y]==1)
            {
                 dfs(grid,x,y);
            }
        }
     }
};

四、被围绕的区域

. - 力扣(LeetCode)

class Solution {
public:
    //正难则反,先去找边界
    //1先找到边界的o,然后用dfs去找 找到了就修改成.
    //2此时矩阵里的o肯定是在区域内的了,直接遍历一遍矩阵修改即可,顺便把.修改成圈
    int m,n;
    void solve(vector<vector<char>>& board) 
    {
      m=board.size(),n=board[0].size();
      //先处理第一行的最后一行
      for(int j=0;j<n;++j)
      {
        if(board[0][j]=='O') dfs(board,0,j);
        if(board[m-1][j]=='O') dfs(board,m-1,j);
      }
      //处理第一列和第二列
      for(int i=0;i<m;++i)
      {
        if(board[i][0]=='O')dfs(board,i,0);
        if(board[i][n-1]=='O') dfs(board,i,n-1);
      }
      //此时剩下位置的O给他改成X,然后.复原成O
      for(int i=0;i<m;++i)
       for(int j=0;j<n;++j)
       {
        if(board[i][j]=='.') board[i][j]='O';
        else if(board[i][j]=='O') board[i][j]='X';
       }
    }
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    void dfs(vector<vector<char>>& board,int i,int j)
    {
       //先将当前位置改成.
       board[i][j]='.';
       for(int k=0;k<4;++k)
       {
        int x=i+dx[k],y=j+dy[k];
        if(x>=0&&x<m&&y>=0&&y<n&&board[x][y]=='O') dfs(board,x,y);
       }
    }
};

五、太平洋大西洋水流问题

. - 力扣(LeetCode)

class Solution {
public:
    //思路,正难则反,用两个标记数组去标记两个大洋的位置
    int m,n;
    vector<vector<int>> ret;//记录返回值
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& h) 
    {
      m=h.size(),n=h[0].size();
     //设置两个标记数组
      vector<vector<bool>> pac(m,vector<bool>(n));
      auto atl=pac;
      //先去找pac
      for(int j=0;j<n;++j) dfs(h,0,j,pac);
      for(int i=0;i<m;++i) dfs(h,i,0,pac);
      //再去找atl
      for(int j=0;j<n;++j) dfs(h,m-1,j,atl);
      for(int i=0;i<m;++i) dfs(h,i,n-1,atl);
      //然后根据两个标记数组,去记录下标
      for(int i=0;i<m;++i)
        for(int j=0;j<n;++j)
          if(pac[i][j]&&atl[i][j])//如果坐标同时被两个数组标记了,就统计最终的结果
            ret.push_back({i,j});
            return ret;
    }
    void dfs(vector<vector<int>>& h,int i,int j, vector<vector<bool>>&vis)
    {
        //先将该点设置为选过
        vis[i][j]=true;
        //定义四个方向,然后去找
        for(int k=0;k<4;++k)
        {
            int x=i+dx[k],y=j+dy[k];
            if(x>=0&&x<m&&y>=0&&y<n&&!vis[x][y]&&h[x][y]>=h[i][j])
              dfs(h,x,y,vis);
        }
    }
};

六、扫雷游戏

. - 力扣(LeetCode)

class Solution {
public:
    int dx[8]={0,0,1,-1,1,1,-1,-1};
    int dy[8]={1,-1,0,0,1,-1,1,-1}; //周围的八个方向
    int m,n;
    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) 
    {
       m=board.size(),n=board[0].size();
       //考虑边界情况,如果是雷,直接返回
       int x=click[0],y=click[1];
       if(board[x][y]=='M') 
       {
        board[x][y]='X';
       }
       else//说明不是雷,dfs去判断该位置的情况
       {
          dfs(board,x,y);
       }
       return board;
    }

    void dfs(vector<vector<char>>& board,int i,int j)
    {
       //进行搜索
       int count=0;//用来数雷
       for(int k=0;k<8;++k)
       {
        int x=i+dx[k],y=j+dy[k];
        if(x>=0&&x<m&&y>=0&&y<n&&board[x][y]=='M') ++count;
       }
       if(count) board[i][j]='0'+count;
       else  //没有雷,就继续去展开
       {
         board[i][j]='B';
         for(int k=0;k<8;++k)
       {
        int x=i+dx[k],y=j+dy[k];
        if(x>=0&&x<m&&y>=0&&y<n&&board[x][y]=='E') dfs(board,x,y);
       }
       }
    }
};

七、衣柜整理

. - 力扣(LeetCode)

class Solution {
public:
    bool vis[100][100];
    int m,n,cnt;
    int ret;
    int wardrobeFinishing(int _m, int _n, int _cnt) 
    {
       m=_m,n=_n,cnt=_cnt;
       ret=0;//统计符合要求的各自的数目
       dfs(0,0);
       return ret;
    }
    void dfs(int i,int j)
    {   
        ++ret;
        vis[i][j]=true;
        if(j+1<n&&check(i,j+1)&&!vis[i][j+1]) dfs(i,j+1);//向右找
        if(i+1<m&&check(i+1,j)&&!vis[i+1][j]) dfs(i+1,j);//向下找
    }
    bool check(int i,int j)
    {
        int temp=0;
        while(i)
        {
            temp+=(i%10);
            i/=10;
        }
        while(j)
        {
            temp+=(j%10);
            j/=10;
        }
        return temp<=cnt;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/521773.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

内容检索(2024.04.07)

随着创作数量的增加&#xff0c;博客文章所涉及的内容越来越庞杂&#xff0c;为了更为方便地阅读&#xff0c;后续更新发布的文章将陆续在此汇总并附上原文链接&#xff0c;感兴趣的小伙伴们可持续关注文章发布动态&#xff01; 本期更新内容&#xff1a; 1. 真实案例分享--P…

能不能换DB吗?--抽象工厂模式

1.1 就不能不换DB吗&#xff1f; 都是换数据库惹的祸。 "我们团队前段时间用.net的C#来开发好一个项目&#xff0c;是给一家企业做的电子商务网站&#xff0c;是用SQL Server作为数据库的&#xff0c;应该说上线后除了开始有些小问题&#xff0c;基本都还可以。而后&#…

政安晨:【Keras机器学习实践要点】(十八)—— 利用视觉转换器进行图像分类

目录 简介 设置 准备数据 配置超参数 使用数据增强 实施多层感知器&#xff08;MLP&#xff09; 将创建修补程序作为一个层 实施补丁编码层 建立 ViT 模型 编译、培训和评估模式 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: T…

Android源码笔记-输入事件(二)

这一节主要了解输入事件的获取&#xff0c;InputReaderThread继承自C的Thread类&#xff0c;Thread类封装了pthread线程工具&#xff0c;提供了与Java层Thread类相似的API。C的Thread类提供了一个名为threadLoop()的纯虚函数&#xff0c;当线程开始运行后&#xff0c;将会在内建…

【Linux实践室】Linux高级用户管理实战指南:创建与删除用户组操作详解

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️任务描述二. ⛳️相关知识2.1 &#x1f514;Linux创建用户组命令2.1.1 知识点讲解2.1.2…

Arduino的OTA在线升级

一、OTA 介绍 OTA是Over-the-Air的缩写&#xff0c;中文意思是空中下载技术。通过移动通信&#xff08;GSM或CDMA&#xff09;的空中接口对SIM卡数据及应用进行远程管理的技术。空中接口可以采用WAP、GPRS、CDMA1X及短消息技术。OTA技术的应用&#xff0c;使得移动通信不仅可以…

读所罗门的密码笔记12_群雄逐鹿(上)

1. 国际电信规则 1.1. 美国坚持互联网自由和极少的内容限制&#xff0c;这一立场肯定会遭到许多国家的反对 1.2. 除去两个各方针锋相对、无法妥协的议题&#xff0c;比如内容限制规定&#xff0c;实际上所有国家都已在打击垃圾邮件和常见网络安全威胁方…

Windows Server 2012 R2安装Web服务器IIS

文章目录 一、打开【服务器管理器】二、点击【添加角色和功能】三、点击【下一步】四、点击【下一步】五、点击【下一步】六、勾选【Web服务器(IIS)】→点击【添加功能】→点击【下一步】七、勾选【.NET Framework 3.5 功能】→点击【下一步】八、点击【下一步】九、点击【下一…

基于H2O AutoML与集成学习策略的房屋售价预测模型研究与实现

项目简述&#xff1a; 本项目采用H2O AutoML工具&#xff0c;针对加州房屋销售价格预测问题进行了深入研究与建模。项目以Kaggle提供的加州房屋 交易数据集为基础&#xff0c;通过数据清洗、特征工程、模型训练与评估等步骤&#xff0c;构建了一种基于集成学习策略的房价预测模…

LeetCode刷题记(二):31~60题

31. 下一个排列 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。…

如何确认RID池是否耗尽,以及手动增加RID池大小

确认RID池是否耗尽&#xff1a; 事件查看器&#xff1a; 在RID主控域控制器上打开事件查看器&#xff0c;导航至“Windows日志 > 应用程序和服务日志 > Microsoft > Windows > Directory Service > Operations”。搜索事件ID 16656和16657。事件ID 16656表明RID…

C++超高精度计时器

#include <chrono> #include <QDebug> #pragma execution_character_set("utf-8") /*1 秒&#xff08;s&#xff09; 1,000 毫秒&#xff08;ms&#xff09; 1,000,000 微秒&#xff08;μs&#xff09; 1,000,000,000 纳秒&#xff08;ns&#xff09…

Leetcode 第 389 场周赛题解

Leetcode 第 389 场周赛题解 Leetcode 第 389 场周赛题解题目1&#xff1a;3083. 字符串及其反转中是否存在同一子字符串思路代码复杂度分析 题目2&#xff1a;3084. 统计以给定字符开头和结尾的子字符串总数思路代码复杂度分析 题目3&#xff1a;3085. 成为 K 特殊字符串需要删…

Fire Smoke - Dynamic Nature

烟雾、火灾和爆炸预制件、着色器的集合。粒子支持HD、URP和标准渲染,自然制造风,因此它们对风速、方向和颤抖做出反应。 包装支持: Unity 2021.2及更高版本 Unity 2021.2 HD RP Unity 2021.2 URP Unity 2021.3及更高版本 Unity 2021.3 LTS HD RP Unity 2021.3 LTS URP Unity…

202112青少年软件编程(Scratch图形化)等级考试试卷(四级)

第1题&#xff1a;【 单选题】 小猫和小狗是非常好的朋友&#xff0c; 他们发明了一种加密方法&#xff1a; 用两位数字代表字母。比如 65 代表 A&#xff0c; 66 代表 B……&#xff0c; 75 代表 K&#xff0c; ……&#xff0c; 78 代表 N&#xff0c; 79 代表 O、 80 代表 …

zdpdjango_argonadmin使用Django开发一个美观的后台管理系统

初始代码 安装依赖 pip install -r requirements.txt生成管理员账户 迁移模型&#xff1a; python manage.py makemigrations python manage.py migrate创建超级用户&#xff1a; python manage.py createsuperuser启动服务 python manage.py runserver浏览器访问&#xf…

ChatGPT官宣新增Dynamic(动态)模式!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

Java中IO流详解

文章目录 字符流问题导入编码表**出现乱码的原因**ASCII表Unicode表汉字存储和展示过程解析问题导入解答 介绍分类字符输出流字符输入流字符缓冲流 特殊操作流转化流对象操作流打印流 工具包Commons-io介绍分类IOUtils类FileUtils类 字符流 问题导入 既然字节流能操作所有文件…

探索Linux的挂载操作

在Linux这个强大的操作系统中&#xff0c;挂载操作是一个基本而重要的概念。它涉及到文件系统、设备和数据访问&#xff0c;对于理解Linux的工作方式至关重要。那么&#xff0c;挂载操作究竟是什么&#xff0c;为什么我们需要它&#xff0c;如果没有它&#xff0c;我们将面临什…

递归学习第一个课

一、递归定义 基本定义 函数自己调用自己&#xff08;通俗第一印象&#xff09;大问题可以拆分小问题&#xff08;拆分&#xff0c;边界&#xff09;大问题与小问题的关系&#xff08;递归关系&#xff09; 为什么拆分小问题&#xff1f; 小问题更容易求解大问题与小问题内部…