floodfill算法_dfs

之前我们用BFS解决floodfil算法

BFS 解决 FloodFill 算法_图像渲染_岛屿数量_被围绕的区域-CSDN博客

下面我们用dfs进行解决

733. 图像渲染

从初始位置开始dfs,找和它值相同的,并在dfs过程中把值改为目标值。因为会改变原数组,不用vis记录经过路径也可以。

边界情况:如果初始位置值结束目标值,那在dfs过程中不会改值,就会出现走重复路径的情况。遇到这种情况,其实是不用进行dfs,原数组就是最终结果。

class Solution {
    vector<int> dx={1,-1,0,0};
    vector<int> dy={0,0,1,-1};
    int m,n;
    int prev,color;
public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int _color) 
    {
        //1.记录要修改的像素值
        prev=image[sr][sc];color=_color;
        //2.处理边界情况 (第一个就是要变成的颜色,就没必要处理)
        if(prev==color) return image;
        //3.二维数组边界 m行数 n列数
        m=image.size(),n=image[0].size();
        dfs(image,sr,sc);
        return image;
    }
    void dfs(vector<vector<int>>& image, int i, int j)
    {
        //进入dfs就更改值
        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);
            }
        }
        return;
    }
};

200. 岛屿数量

class Solution {
    int dx[4]={1,-1,0,0};
    int dy[4]={0,0,1,-1};
    bool vis[301][301];
    int m,n;
public:
    int numIslands(vector<vector<char>>& grid) {
        int re=0;
        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]=='1'&&!vis[i][j])
                {
                    dfs(grid,i,j); re++;
                }
            }
        }
        return re;
    }
    void dfs(vector<vector<char>>& grid,int i,int j)
    {
        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]&&grid[x][y]=='1')
           {
               dfs(grid,x,y);
           }
       }
       return;
    }
};

695. 岛屿的最大面积

每遍历到一个1且没有标记过,就从该位置进行dfs,进入dfs就标记并记录当前面积,dfs结束获取这一块1的面积。

class Solution {
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    int m,n;
    bool vis[51][51];
    //记录“1”块的面积
    int count=0;
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        m=grid.size(),n=grid[0].size();
        int re=0;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(!vis[i][j]&&grid[i][j]==1)
                {
                    count=0;
                    dfs(grid,i,j);
                    re=max(re,count);
                }
            }
        }
        return re;
    }
    int dfs(vector<vector<int>>& grid,int i,int j)
    {
        //进入一个面积+1 标记
        count++;
        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]&&grid[x][y]==1)
            {
                dfs(grid,x,y);
            }
        }
        return count;
    }
};

130. 被围绕的区域

class Solution {
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
    bool vis[201][201];
    int m, n;

public:
    void solve(vector<vector<char>>& board) {
        m = board.size(), n = board[0].size();
        // 1. 先处理边界上的 'O' 联通块 对应的vis改为1
        for (int j = 0; j < n; j++) {
            if (board[0][j] == 'O')
                dfs(board, 0, j);
            if (board[m - 1][j] == 'O'&&!vis[m-1][j])
                dfs(board, m - 1, j);
        }
        for (int i = 0; i < m; i++) {
            if (board[i][0] == 'O'&&!vis[i][0])
                dfs(board, i, 0);
            if (board[i][n - 1] == 'O'&&!vis[i][n-1])
                dfs(board, i, n - 1);
        }
        // 2. 更改
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                if (board[i][j] == 'O'&&!vis[i][j])
                    board[i][j] = 'X';
    }
    void dfs(vector<vector<char>>& board, int i, int j)
    {
        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]&&board[x][y]=='O')
            {
                dfs(board,x,y);
            }
        }
        return;
    }
};

417. 太平洋大西洋水流问题

每个格子上都有水,水从高处流向低处,问那个格子的水可以流向太平洋和大西洋。

思路一:对每个格子都进行dfs,找可以流向两个洋的格子。

时间复杂度太高,不推荐

class Solution {
    int dx[4]={1,-1,0,0};
    int dy[4]={0,0,1,-1};
    vector<vector<int>> re;
    bool vis[201][201];
    bool P=false,A=false;
    int m,n;
public:
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& h) {
        m=h.size(),n=h[0].size();
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                P=false,A=false;
                vis[i][j]=true;
                dfs(h,i,j);
                vis[i][j]=false;
                if(P&&A) re.push_back({i,j});
            }
        }
        return re;
    }
    void dfs(vector<vector<int>>& h,int i,int j)
    {
        if(i==m-1||j==n-1)
            A=true;
        if(i==0||j==0) 
            P=true;
        if(A&&P) return;
        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])
            {
                vis[x][y]=true;
                dfs(h,x,y);
                vis[x][y]=false;
            }
        }
        return;
    }
};

方法二:正难则反

水从高到低,反过来水从低到高,路径是一样的。

1.看临边是Pac洋的格子从低到高走,四周的格子比它大就可以走。(用绿色标记走过的格子)

2.看临边是Atl洋的格子从低到高走,四周的格子比它大就可以走。(用红色标记走过的格子)

它们相交的格子就是可以流向两个洋的格子

因为有两种标记,vis图要有两个。对靠近Pac洋的格子dfs进行标记,还要对靠近Atl洋的格子dfs进行标记。两个vis图都为true的位置为目标位置。

注意:vis1 vis2要定义成全局变量 进行传参 保存改变结果

或者在函数内定义成vector<vector<bool> vis(m,vector<bool>(n));进行引用&传参

class Solution {
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
    vector<vector<int>> re;
    bool vis1[201][201];
    bool vis2[201][201];
    int m, n;

public:
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& h) {
        m = h.size();
        n = h[0].size();
        
        // // 初始化访问数组
        // memset(vis1, false, sizeof(vis1));
        // memset(vis2, false, sizeof(vis2));

        // 从每个边缘开始 DFS
        for (int i = 0; i < m; i++) 
        {
            for (int j = 0; j < n; j++) 
            {
                if (i == 0 || j == 0)  // 太平洋
                    dfs(h, i, j, vis1);
                if (i == m - 1 || j == n - 1)  // 大西洋
                    dfs(h, i, j, vis2);
            }
        }

        // 收集同时到达太平洋和大西洋的坐标
        for (int i = 0; i < m; i++) 
        {
            for (int j = 0; j < n; j++) 
            {
                if (vis1[i][j] && vis2[i][j]) 
                    re.push_back({i, j});
            }
        }
        return re;
    }

    void dfs(vector<vector<int>>& h, int i, int j, bool vis[201][201]) 
    {
        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);
            }
        }
    }
};

529. 扫雷游戏

在eg1中click位置点击,该格四周没有地雷,改为B,并向四周dfs找E未挖出的格子。如果该格周围有地雷就改为周围地雷数,不进行dfs。

点到地雷就更改并返回。

我们可以先用map数组记录每个格子四周有多少地雷,这样在判断该格四周是否有地雷就不用遍历周围 直接看map中是否有数就行。

class Solution {
    int map[51][51]={0};
    int dx[8]={1,-1,0,0,1,-1,1,-1};
    int dy[8]={0,0,1,-1,-1,1,1,-1};
    int m,n;
public:
    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
        m=board.size(),n=board[0].size();
        //在map图中记录该格周围有多少地雷
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
            {
                if(board[i][j]=='M')
                {
                    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 ) map[x][y]++;
                    }
                }
            }
        int x=click[0],y=click[1];
        //遇到地雷更改并返回
        if(board[x][y]=='M')
        {
            board[x][y]='X';
            return board;
        }
        //遇到E分两情况 四周有地雷和无地雷
        else
        {
            dfs(board,x,y);
        }
        return board;
    }
    void dfs(vector<vector<char>>& board,int i,int j)
    {
        //1.周围有地雷 E变为周围地雷数
        if(map[i][j]) board[i][j]='0'+map[i][j];
        //2.没有地雷 E变B并以该各为起点dfs找E未挖出的格
        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);
                }
            }
        }
        return;
    }
};

LCR 130. 衣橱整理

从(0,0)进行dfs遍历所有格子,找出符合条件的格子。不能重复记录符合条件的格子,用vis记录走过的路径。

class Solution {
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    bool vis[101][101];
    int m,n,cnt;
    int re=0;
public:
    int wardrobeFinishing(int _m, int _n, int _cnt) {
        m=_m,n=_n,cnt=_cnt;
        dfs(0,0);
        return re;
    }
    void dfs(int i,int j)
    {
        vis[i][j]=true;
        int tmp1=i,tmp2=j,sum=0;
        while(tmp1||tmp2)
        {
            sum+=tmp1%10;
            tmp1/=10;
            sum+=tmp2%10;
            tmp2/=10;
        }
        if(sum>cnt) return;
        else re++;
        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])
            {
                dfs(x,y);
            }
        }
        return;
    }
};

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

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

相关文章

40% 降本:多点 DMALL x StarRocks 的湖仓升级实战

小编导读&#xff1a; 多点 DMALL 成立于2015年&#xff0c;持续深耕零售业&#xff0c;为企业提供一站式全渠道数字零售解决方案 DMALL OS。作为 DMALL OS 数字化能力的技术底座&#xff0c;大数据平台历经多次迭代平稳支撑了公司 To B 业务的快速开展。随着国家产业升级和云原…

AI-Talk开发板之超拟人

一、说明 运行duomotai_ap sdk下的LLM_chat例程&#xff0c;实现开发板和超拟人大模型进行语音交互&#xff0c;支持单轮和多轮交互。 二、SDK更新 v2.3.0及以上的SDK版本才支持超拟人&#xff0c;如果当前SDK在v2.3.o以下&#xff0c;需要更新SDK。在SDK目录(duomotai_ap)下…

graylog+sidecar通过docker-compose部署并采集SSH登录日志

文章目录 前言一、graylog日志系统数据流向清洗图二、资源准备及部署1.docker-compose部署2.准备docker-compose.yml文件3.安装graylog-sidecar并配置4.给sidecar创建token 三、graylog-WEB配置采集SSH日志1.配置Inputs2.创建sidecar采集器3.将页面创建好的sidecar与服务器绑定…

【Vue.js】监听器功能(EventListener)的实际应用【合集】

目录 &#x1f914;在实际开发过程中&#xff0c;我遇到了一个颇为棘手的小问题 &#x1f60b;解决这个小问题 问题出现的原因剖析 解决方法阐述 问题成功解决&#xff01;​ &#x1f4d6;相关知识总结 基本概念 使用方法 实际应用场景 &#x1f914;在实际开发过程中…

2023年区块链职业技能大赛——区块链应用技术(一)模块一

模块一:区块链产品方案设计及系统运维: 任务1-1:区块链产品需求分析与方案设计 1.依据给定区块链食品溯源系统的业务架构图&#xff0c;对考题进行业务分析&#xff0c;可能多的去考虑一个业务系统所需要的模块&#xff0c;使用Visio或思维导图工具展现本系统的基本设计概念和…

【HarmonyOS应用开发——ArkTS语言】欢迎界面(启动加载页)的实现【合集】

目录 &#x1f60b;环境配置&#xff1a;华为HarmonyOS开发者 &#x1f4fa;演示效果&#xff1a; &#x1f4d6;实验步骤及方法&#xff1a; 一、在media文件夹中添加想要使用的图片素材​ 二、在entry/src/main/ets/page目录下创建Welcome.ets文件 1. 整体结构与组件声…

Flutter Android修改应用名称、应用图片、应用启动画面

修改应用名称 打开Android Studio&#xff0c;打开对应项目的android文件。 选择app下面的manifests->AndroidManifest.xml文件&#xff0c;将android:label"bluetoothdemo2"中的bluetoothdemo2改成自己想要的名称。重新启动或者重新打包&#xff0c;应用的名称…

MES管理系统如何解决企业制造瓶颈

在当今全球化与信息化高度融合的时代&#xff0c;制造业作为支撑国家经济发展的关键产业&#xff0c;正处于发展的十字路口&#xff0c;面临着一系列严峻挑战。从日常所需的各类用品到先进的高端工业产品&#xff0c;制造业的稳定发展对经济的稳健运行至关重要&#xff0c;一旦…

Maven 详细配置:Maven settings 配置文件的详细说明

Maven settings 配置文件是 Maven 环境的重要组成部分&#xff0c;它用于定义用户特定的配置信息和全局设置&#xff0c;例如本地仓库路径、远程仓库镜像、代理服务器以及认证信息等。settings 文件分为全局配置文件&#xff08;settings.xml&#xff09;和用户配置文件&#x…

【C++】18.继承

文章目录 1.继承的概念及定义1.1 继承的概念1.2 继承定义1.2.1定义格式1.2.2继承关系和访问限定符1.2.3继承基类成员访问方式的变化 1.3 继承类模板 2.基类和派生类对象赋值转换3.继承中的作用域3.1 隐藏规则&#xff1a;3.2 考察继承作用域相关选择题 4.派生类的默认成员函数4…

声音是如何产生的

一、音频概述 RTMP中一般音频采用aac编码&#xff0c;采样率为44100HZ, 每帧1024采样&#xff0c;帧率43&#xff0c;23.2ms一帧 RTC中一般音频采用opus编码&#xff0c;采样率为48000HZ&#xff0c;每帧480采样&#xff0c;帧率100&#xff0c;10ms一帧 通道数&#xff08;c…

什么是中间件中间件有哪些

什么是中间件&#xff1f; 中间件&#xff08;Middleware&#xff09;是指在客户端和服务器之间的一层软件组件&#xff0c;用于处理请求和响应的过程。 中间件是指介于两个不同系统之间的软件组件&#xff0c;它可以在两个系统之间传递、处理、转换数据&#xff0c;以达到协…

问题清除指南|关于num_classes与 BCELoss、BCEWithLogitsLoss 和 CrossEntropyLoss 的关系

前言&#xff1a;关于「 num_classes 1 」引发的探究。 2024年尾声&#xff0c;学弟问到一个问题&#xff1a;在研究工作 CNNDetection 的github开源代码 networks/trainer.py 文件的 line 27 self.model resnet50(num_classes1) 中&#xff0c;变量 num_classes 的值为1&…

FinDKG: 用于检测金融市场全球趋势的动态知识图谱与大型语言模型

“FinDKG: Dynamic Knowledge Graphs with Large Language Models for Detecting Global Trends in Financial Markets” 论文地址&#xff1a;https://arxiv.org/pdf/2407.10909 摘要 动态知识图&#xff08;DKG&#xff09;能够表示对象间随时间变化的关系&#xff0c;适用于…

Robot---奇思妙想轮足机器人

1 背景 传统机器人有足式、轮式、履带式三种移动方式&#xff0c;每种移动方式都有各自的优缺点。轮式机器人依靠车轮在地面上移动&#xff0c;能源利用率高、移动速度快&#xff0c;但是仅以轮子与地面接触&#xff0c;缺乏越障能力和对复杂地形的适应能力&#xff0c;尤其面对…

高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图

目录 高效工作流&#xff1a;用Mermaid绘制你的专属流程图 一、流程图的使用场景 1.1、流程图flowChart 1.2、使用场景 二、如何使用mermaid画出优雅的流程图 2.1、流程图添加图名 2.2、定义图类型与方向 2.3、节点形状定义 2.3.1、规定语法 2.3.2、不同节点案例 2.…

.NET框架用C#实现PDF转HTML

HTML作为一种开放标准的网页标记语言&#xff0c;具有跨平台、易于浏览和搜索引擎友好的特性&#xff0c;使得内容能够在多种设备上轻松访问并优化了在线分享与互动。通过将PDF文件转换为HTML格式&#xff0c;我们可以更方便地在浏览器中展示PDF文档内容&#xff0c;同时也更容…

Tableau数据可视化与仪表盘搭建-可视化原则及BI仪表盘搭建

目录 可视化原则 BI仪表盘搭建 仪表盘搭建原则 明确仪表盘主题 仪表盘主题拆解 开发设计工作表 经营情况总览&#xff1a;突出显示的文字 经营数据详情&#xff1a;表格 每日营收数据&#xff1a;多轴折线图 每日流量数据&#xff1a;双轴组合图 新老客占比&#xf…

AIA - APLIC之三(附APLIC处理流程图)

本文属于《 RISC-V指令集基础系列教程》之一,欢迎查看其它文章。 1 APLIC复位 APLIC复位后,其所有状态都变得有效且一致,但以下情况除外: 每个中断域的domaincfg寄存器(spec第 4.5.1 节);可能是machine-level interrupt domain的MSI地址配置寄存器(spec第4.5.3 和4.5…

unity学习5:创建一个自己的3D项目

目录 1 在unity里创建1个3D项目 1.1 关于选择universal 3d&#xff0c;built-in render pipeline的区别 1.2 创建1个universal 3d项目 2 打开3D项目 2.1 准备操作面板&#xff1a;操作界面 layout,可以随意更换 2.2 先收集资源&#xff1a;打开 window的 AssetStore 下载…