力扣刷题笔记——图的BFS与DFS

​​​​​​力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目描述

有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。 省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。 给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。 返回矩阵中 省份 的数量。

这个问题描述了一个典型的图论问题,涉及到找出图中的连通分量的数量。在这个场景中,每个城市可以看作图中的一个节点,如果两个城市直接相连,那么这两个城市间就有一条边。问题的目标是找出图中有多少个完全独立的连通分量,即“省份”。

给定的矩阵 isConnected 实际上是一个邻接矩阵,表示了城市之间的连接状态。isConnected[i][j] = 1 表示城市 i 和城市 j 直接相连,而 isConnected[i][j] = 0 表示两者不直接相连。

解题方法

为了解决这个问题,可以使用深度优先搜索(DFS)或广度优先搜索(BFS)算法来遍历图,并找出所有连通分量。

使用深度优先搜索(DFS)
  1. 初始化:创建一个标记数组,用于记录每个城市是否已被访问。
  2. 遍历每个城市:对于每个城市,如果它还没有被访问,那么从这个城市开始进行一次深度优先搜索,这代表了一个新的省份。
  3. 深度优先搜索:在 DFS 过程中,访问当前城市的所有未访问邻接城市,将其标记为已访问。
  4. 计数:每完成一次完整的 DFS,省份的数量加一。
class Solution {
public:
    void dfs(int j,vector<vector<int>>&graph,vector<bool>&vis){
        for(int i=0;i<graph.size();++i){
            if(!vis[i]&&graph[j][i]==1){
                vis[i]=true;
                dfs(i,graph,vis);
            }
        }
    }
    int findCircleNum(vector<vector<int>>& isConnected) {
        int n=isConnected.size();
        vector<bool>vis(n,false);
        int ans=0;
        for(int j=0;j<isConnected.size();j++){
            if(!vis[j]){
                ans++;
                dfs(j,isConnected,vis);
            }
        }
        return ans;
    }
};

 

使用广度优先搜索(BFS)
  1. 初始化:创建一个标记数组,用于记录每个城市是否已被访问。
  2. 遍历每个城市:对于每个未访问的城市,进行一次广度优先搜索。
  3. 广度优先搜索:使用队列来实现 BFS。将当前城市的所有未访问邻接城市加入队列,并标记为已访问。
  4. 计数:每完成一次完整的 BFS,省份的数量加一。
class Solution {
public:
    int bfs(vector<vector<int>>&graph){
        int size=graph.size();
        int count=0;
//记录访问过的城市
        vector<bool>vis(size,false);
//对每个城市进行遍历
        for(int i=0;i<size;i++){
//如果是第一次访问当前城市则对这个城市的所有相连城市进行遍历
            if(!vis[i]){
                queue<int>q;
                q.push(i);
                vis[i]=true;
//广度遍历所有相连城市并放入队列中
                while(!q.empty()){
                    int curr=q.front();q.pop();

                    for(int j=0;j<size;++j){
                        if(!vis[j]&&graph[curr][j]==1){
                            vis[j]=true;
                            q.push(j);
                        }
                    }
                }
                count++;
            }
        }
        return count;
    }
    int findCircleNum(vector<vector<int>>& isConnected) {
        return bfs(isConnected);
    }
};

 

代码解释
  1. BFS 函数:该函数实现广度优先搜索来找出图中连通分量的数量。
  2. 外层循环:遍历每个节点,开始新的 BFS 搜索未访问的节点。
  3. 内部循环:对于当前节点 curr,遍历所有其他节点,检查是否存在边(graph[curr][j] == 1),并且该节点未被访问(!vis[j])。如果是,就将其加入队列并标记为已访问。
  4. 计数:每完成一次 BFS 循环,计数器 count 增加,代表找到一个新的连通分量(省份)。
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我我我想出去玩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值