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 };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具