算法——BFS算法

news2024/9/22 15:37:09

1. 什么是BFS算法

BFS(广度优先搜索,Breadth-First Search)算法是一种用于图和树等数据结构中进行搜索的基本算法。它从指定的起始节点开始,逐层地向外扩展搜索,直到找到目标节点或遍历完整个图。

BFS算法的基本思想是:先访问起始节点,然后依次访问起始节点的邻居节点,再依次访问邻居节点的邻居节点,以此类推,直到搜索到目标节点或者遍历完整个图。BFS算法使用队列来辅助实现节点的遍历顺序,保证每一层的节点按顺序访问。 

2. 应用实例

①BFS解决FloodFill问题

1. 图像渲染

题目链接:733. 图像渲染 - 力扣(LeetCode)

解析:题目的要求是对一大批性质相同的连续区域进行处理,我们可以使用BFS来进行处理,代码如下

class Solution 
{
public:
    int dx[4] = {1,-1,0,0};
    int dy[4] = {0,0,1,-1};
    int m,n;
    int check[51][51] = {0};

    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) 
    {
        m = image.size(), n = image[0].size();
        queue<pair<int, int>> q;
        q.push({sr,sc});

        while (!q.empty())
        {
            int sz = q.size();
            while (sz--)
            {
                auto pair = q.front();
                int a = pair.first, b = pair.second;
                int prevcolor = image[a][b];
                image[a][b] = color;
                q.pop();
                for (int i = 0; i < 4; i++)
                {
                    int x = a + dx[i], y = b + dy[i];
                    if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] == prevcolor && !check[x][y])
                    {
                        q.push({x, y});
                        check[x][y] = 1;
                    }
                }
            }
        }

        return image;
    }
};

2. 岛屿数量

题目链接:200. 岛屿数量 - 力扣(LeetCode)

解析:根据题目要求,我们在每次遇见‘1’时,从这个位置开始进行一次bfs将所有相邻为‘1’的区域置为‘0’,在每次进入后记录一次岛屿个数,遍历一遍之后就能得到答案,代码如下

class Solution 
{
public:
    int dx[4] = {0,0,1,-1};
    int dy[4] = {1,-1,0,0};
    int m,n;
    int check[301][301] = {0};

    void bfs(vector<vector<char>>& grid, int row, int col)
    {
        queue<pair<int, int>> q;
        q.push({row, col});

        while (!q.empty())
        {
            int sz = q.size();
            while (sz--)
            {
                auto [a, b] = q.front();
                q.pop();
                grid[a][b] = '0';
                for (int i = 0; i < 4; i++)
                {
                    int x = a + dx[i], y = b + dy[i];
                    if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1' && !check[x][y])
                    {
                        q.push({x, y});
                        check[x][y] = 1;
                    } 
                }
            }
        }
    }

    int numIslands(vector<vector<char>>& grid) 
    {
        int count = 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') 
                {
                    bfs(grid, i, j);
                    count++;
                }

        return count;
    }
};

3. 岛屿的最大面积

题目链接:695. 岛屿的最大面积 - 力扣(LeetCode)

解析:我们可以在遇见值为1的区域时,我们对其使用一次bfs统计该区域岛屿大小,边统计边将其置为0,最后与ret相比较,让ret更新为最大值并返回,代码如下

class Solution 
{
public:
    int m, n, ret;
    int dx[4] = {1,-1,0,0};
    int dy[4] = {0,0,1,-1};
    int check[51][51] = {0};

    void bfs(vector<vector<int>>& grid, int row, int col)
    {
        int area = 0;
        queue<pair<int, int>> q;
        q.push({row, col});

        while (!q.empty())
        {
            int sz = q.size();
            while (sz--)
            {
                auto [a, b] = q.front();
                area++;
                q.pop();
                grid[a][b] = 0;
                for (int i = 0; i < 4; i++)
                {
                    int x = a + dx[i], y = b + dy[i];
                    if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && !check[x][y])
                    {
                        q.push({x, y});
                        check[x][y] = 1;
                    }
                }
            }
        }

        ret = max(ret, area);
    }

    int maxAreaOfIsland(vector<vector<int>>& grid) 
    {
        ret = 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) bfs(grid, i, j);

        return ret;
    }
};

4. 被围绕的区域

题目链接:130. 被围绕的区域 - 力扣(LeetCode)

解析:分析题意,我们可以先遍历图形的四周,遇见'O'就进行一次bfs,将所有与边缘相连的'O'均设置为'A'(随意),然后遍历整个图形,将为‘O’的改为‘X’,为‘A’的改为‘O’即可,代码如下

class Solution 
{
public:
    int m,n;
    int dx[4] = {1,-1,0,0};
    int dy[4] = {0,0,1,-1};
    int check[201][201] = {0};

    void bfs(vector<vector<char>>& board, int row, int col, char flag)
    {
        queue<pair<int, int>> q;
        q.push({row, col});

        while (!q.empty())
        {
            int sz = q.size();
            while (sz--)
            {
                auto [a, b] = q.front();
                q.pop();
                check[a][b] = 1;
                board[a][b] = flag;
                for (int i = 0; i < 4; i++)
                {
                    int x = a + dx[i], y = b + dy[i];
                    if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O' && !check[x][y])
                    {
                        q.push({x, y});
                        check[x][y] = 1;
                    }
                }
            }
        }
    }

    void solve(vector<vector<char>>& board) 
    {
        m = board.size(), n = board[0].size();
        for (int i = 0; i < m; i++) 
        {
            if (board[i][0] == 'O') bfs(board, i, 0, 'A');
            if (board[i][n-1] == 'O') bfs(board, i, n-1, 'A');
        }
        for (int j = 0; j < n; j++) 
        {
            if (board[0][j] == 'O') bfs(board, 0, j, 'A');
            if (board[m-1][j] == 'O') bfs(board, m-1, j, 'A');
        }

        for (auto& v : board)
            for (auto& ch : v) 
                if (ch == 'O') ch = 'X';
                else if (ch == 'A') ch = 'O';
    }
};

②BFS解决最短路问题

1. 迷宫中离入口最近的出口

题目链接:1926. 迷宫中离入口最近的出口 - 力扣(LeetCode)

解析:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R可视化:桑基图展示数据层流动

介绍 以桑基图形式展示数据分布情况 加载R包 knitr::opts_chunk$set(message = FALSE, warning = FALSE) library(tidyverse) library(ggalluvial)# rm(list = ls()) options(stringsAsFactors = F) options(future.globals.maxSize = 10000 * 1024^2) 导入数据 metadata…

【Qt 学习笔记】Qt常用控件 | 显示类控件 | Label的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 显示类控件 | Label的使用及说明 文章编号&#xff1a;Q…

CentOS 系统的优缺点

CentOS &#xff08;社区企业操作系统的缩写&#xff09;是一个基于红帽企业 Linux (RHEL)的免费开源发行版&#xff0c; 旨在为服务器和工作站提供稳定、可靠和安全的平台。 不应将其与CentOS Stream 混淆&#xff0c;后者是即将发布的 RHEL 版本的上游开发平台。 CentOS Li…

虚拟化及Docker基础

一、虚拟化 1.1 云端 1.2 云计算服务模式分层 1.3 虚拟化架构 1.3.1 寄居架构 1.3.2 原生架构 1.4 虚拟化产品 1.4.1 仿真虚拟化产品&#xff08;对系统硬件没有要求&#xff0c;性能最低&#xff09; 1.4.2 半虚拟化 &#xff08;虚拟机可以使用真机物理机&#xff09…

垃圾渗滤液如何有效处理

垃圾渗滤液&#xff0c;通常称为垃圾填埋场的渗滤液&#xff0c;是一种复杂的高浓度有机废水&#xff0c;含有多种有毒有害物质。有效处理垃圾渗滤液对环境保护至关重要。这里是一些常见且有效的处理方法&#xff1a; ### 预处理 ##### 1. 调节池 - **pH调整**&#xff1a;通过…

【招聘】数通,云计算岗位持续招聘中

北京、南京、成都、贵州、杭州、深圳、上海 云计算HCS 薪资:8-25k 岗位描述: 1、制定网络安全技术规范及工作标准、负责全国工程团队技术培训及人员培养 2、全国项目技术支持、协助开展广域网的设计、规划、实施及方案交流工作 3、承担公司中、大型集成项目管理&#xff0c;负…

7、线上系统部署时如何设置JVM内存大小?

7.1、前文回顾 让我们先来回顾一下我们已经学到的知识。现在,大家应该都明白了,在我们日常编写代码时,所创建的对象通常是首先在新生代区域进行分配的。然后,当一些方法执行完毕后,大部分位于新生代区域中的对象将不再被引用,从而变成垃圾对象。如下图所示: 随着程序…

Spring MVC后续

目录 1 响应 1.1 返回静态页面 1.2 返回数据ResponseBody 1.3 返回HTML代码片段 1.4 返回JSON 1.5 设置状态码 1 响应 1.1 返回静态页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>index页面&…

项目管理中,项目团队如何高效的协作与沟通?

目 录 一、项目团队高效的协作与沟通&#xff0c;可以通过以下几个方面来实现&#xff1a; 二、如何在项目团队中明确和共享愿景以提高协作效率&#xff1f; 三、有效的沟通策略在项目管理中的应用案例有哪些&#xff1f; 四、建立哪些具体的沟通机制可以提升团队协作效率…

创享大会分会场—“职棱起来”《职业生涯画布工作坊》

会议主题&#xff1a;创享大会分会场—“职棱起来”《职业生涯画布工作坊》 会议时间&#xff1a;5月25日&#xff08;周六&#xff09;13:30—16:30 会议地点&#xff1a;北京希尔顿欢朋酒店&#xff08;大红门&#xff09; 特邀嘉宾&#xff1a;姚冬&#xff08;冬哥&…

探秘Meta AI巨无霸:LLaMA大语言模型解析!

目录 福利&#xff1a;文末有chat-gpt纯分享&#xff0c;无魔法&#xff0c;无限制 Abstract Introduction Approach Pre-training Data Tokenizer Architecture Pre-normalization SwiGLU激活函数 Rotary Embeddings Optimizer Main results 总结 Meta的LLaMA大模…

【QML】State组件

State(状态)组件是一组来自默认配置的批处理更改。所有项都有一个默认状态&#xff0c;该状态定义对象和属性值的默认配置。可以通过将State项添加到states属性来定义新的状态&#xff0c;以允许项在不同的配置之间切换。 State组件的基本用法如下&#xff1a; Window {id: …

如何优化必应bing搜索国内广告投放效果?

在当今竞争激烈的数字营销环境中&#xff0c;必应Bing作为全球第二大搜索引擎&#xff0c;在中国市场正逐渐成为企业不可忽视的广告投放平台。其高质量的用户基础与精准的定位能力&#xff0c;为广告主提供了新的增长机遇。然而&#xff0c;如何在必应Bing上实现广告效果的最大…

基于springboot+vue+Mysql的汉服推广网站

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

列车tcn网络mvb主站发送代码流程解析

TCN-列车通信网络概述 机车车辆通信网络&#xff08;TCN-列车通信网络&#xff09;的基本组件是在整个列车单元中提供数据通信的有线列车总线&#xff08;WTB&#xff09;和用于在车辆或固定连接车辆组&#xff08;组成&#xff09;内进行数据交换&#xff08;通信&#xff09…

公钥密码学Public-Key Cryptography

公钥或非对称密码学的发展是整个密码学历史上最伟大的&#xff0c;也许是唯一真正的革命。The development of public-key, or asymmetric, cryptography is the greatest and perhaps the only true revolution in the entire history of cryptography. 公钥算法基于数学函数…

aardio - 【库】图片转字符画

库文件及例程下载&#xff1a;https://aardio.online/thread-261.htm

【linux】Bad owner or permissions on

在root用户下执行scp操作向另外一个节点拷贝文件时发生了如下错误&#xff1a; Bad owner or permissions on /etc/crypto-policies/back-ends/openssh.config 我们查看他的权限时发现它所链接的文件权限为777 解决方法就是&#xff1a; chmod 600 /etc/crypto-policies/back-e…

组装一台FPV穿越机无人机,小白级保姆教程!

穿越机是无人机的一种类型&#xff0c;但与常见的无人机相比&#xff0c;它更倾向于被归类为航模。穿越机通常没有自主巡航能力&#xff0c;并且许多玩家喜欢自己购买配件进行组装。它的最高时速可以达到120km/h至230km/h。 配件清单 DJI O3 天空端&#xff0c;DJI Goggles 2&…

[柏鹭杯 2021]试试大数据分解?

题目&#xff1a;&#xff08;NSSCTF | 在线CTF平台&#xff09; 题目就是如此&#xff0c;我没看到有5个不同的文本&#xff0c;其中最后一个文本以pem后缀&#xff0c;所以我们先来了解一下什么是pem格式。 PEM 格式 PEM格式通常用于数字证书认证机构&#xff08;Certifica…