323. 无向图中连通分量的数目

323. 无向图中连通分量的数目

你有一个包含 n 个节点的图。给定一个整数 n 和一个数组 edges ,其中 edges[i] = [ai, bi] 表示图中 ai 和 bi 之间有一条边。

返回 图中已连接分量的数目 。

 

示例 1:

n = 5
edges = [[0, 1], [1, 2], [3, 4]]

示例 2:

n = 5,
edges = [[0,1], [1,2], [2,3], [3,4]]

 

提示:

  • 1 <= n <= 2000
  • 1 <= edges.length <= 5000
  • edges[i].length == 2
  • 0 <= ai <= bi < n
  • ai != bi
  • edges 中不会出现重复的边

方法一:采用BFS

复制代码
 1 class Solution {
 2 public:
 3     void bfs(vector<vector<int>> &adj, int i, vector<bool> &visited) {
 4         queue<int> q;
 5         q.push(i);
 6         visited[i] = true;
 7         while (!q.empty()) {
 8             int size = q.size();
 9             for (int i = 0; i < size; i++) {
10                 int tmp = q.front();
11                 q.pop();
12                 // 将与tmp连通且未被访问过的点都入队列
13                 for (auto &val : adj[tmp]) {
14                     if (!visited[val]) {
15                         q.push(val);
16                         visited[val] = true;
17                     }
18                 }
19             }
20         }
21     }
22     int countComponents(int n, vector<vector<int>>& edges) {
23         // 1、采用邻接表构建无向连通图
24         vector<vector<int>> adj;
25         adj.resize(n);
26         for (auto &edge : edges) {
27             adj[edge[0]].push_back(edge[1]);
28             adj[edge[1]].push_back(edge[0]);
29         }
30         // 2、采用BFS获取连通分量个数
31         int cnt = 0;
32         vector<bool> visited(n, false);
33         for (int i = 0; i < n; i++) {
34             if (!visited[i]) {
35                 bfs(adj, i, visited);
36                 cnt++;
37             }
38         }
39         return cnt;
40     }
41 };
复制代码

 

方法二:采用并查集(因为只要求计算连通分量数)

复制代码
 1 class UnionFind {
 2 public:
 3     void init(int n) {
 4         parent.resize(n);
 5         cnt = n; // 初始时所有顶点都指向自己,连通分量数为节点数
 6         for (int i = 0; i < n; i++) {
 7             parent[i] = i; // 初始时所有节点都指向自己
 8         }
 9     }
10     int findRoot(int x) {
11         int root = x;
12         // 获取x的根节点
13         while (root != parent[root]) {
14             root = parent[root];
15         }
16         // 路径压缩
17         while (x != root) {
18             int next = parent[x];
19             parent[x] = root;
20             x = next;
21         }
22         return root;
23     }
24     void unify(int x, int y) {
25         int xRoot = findRoot(x);
26         int yRoot = findRoot(y);
27         if (xRoot == yRoot) {
28             return;
29         }
30         parent[xRoot] = yRoot;
31         cnt--;
32         return;
33     }
34     int getConnectedCnt() {
35         return cnt;
36     }
37 private:
38     vector<int> parent; // 每个顶点的根节点
39     int cnt; // 连通分量数
40 };
41 class Solution : public UnionFind {
42 public:
43     int countComponents(int n, vector<vector<int>>& edges) {
44         if (edges.size() == 0 || edges[0].size() == 0) {
45             return n;
46         }
47         init(n);
48         // 1、遍历邻接表(边)合并连通节点
49         for (unsigned int i = 0; i < edges.size(); i++) {
50             unify(edges[i][0], edges[i][1]);
51         }
52         return getConnectedCnt();
53     }
54 };
复制代码
posted @   跳动的休止符  阅读(292)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示