323. Number of Connected Components in an Undirected Graph
At a Glance
- Topic: graphs
- Pattern: Union-Find or DFS/BFS
- Difficulty: Medium
- Companies: Amazon, Google, Microsoft, Meta, Apple
- Frequency: Medium
- LeetCode: 323 (Premium)
Problem (one-liner)
Given n nodes 0..n-1 and a list of undirected edges, return the number of connected components.
Recognition Cues
- Static connectivity count
- Undirected edges — Union-Find merge or DFS flood
Diagram
At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.
Loading diagram…
Approaches
- Adjacency + DFS —
O(n+e)time,O(n+e)space. - Union-Find —
O(n α(n))— compact for edge-list input.
Optimal Solution
Go
type unionFind struct {
parent []int
}
func newUnionFind(size int) *unionFind {
parent := make([]int, size)
for index := range parent {
parent[index] = index
}
return &unionFind{parent: parent}
}
func (finder *unionFind) find(node int) int {
if finder.parent[node] != node {
finder.parent[node] = finder.find(finder.parent[node])
}
return finder.parent[node]
}
func (finder *unionFind) union(left int, right int) {
rootLeft := finder.find(left)
rootRight := finder.find(right)
if rootLeft != rootRight {
finder.parent[rootRight] = rootLeft
}
}
func countComponents(nodeCount int, edges [][]int) int {
finder := newUnionFind(nodeCount)
for _, edge := range edges {
finder.union(edge[0], edge[1])
}
roots := map[int]struct{}{}
for node := 0; node < nodeCount; node++ {
roots[finder.find(node)] = struct{}{}
}
return len(roots)
}JavaScript
class UnionFind {
constructor(size) {
this.parent = Array.from({ length: size }, (_, index) => index);
}
find(node) {
if (this.parent[node] !== node) {
this.parent[node] = this.find(this.parent[node]);
}
return this.parent[node];
}
union(left, right) {
const rootLeft = this.find(left);
const rootRight = this.find(right);
if (rootLeft !== rootRight) {
this.parent[rootRight] = rootLeft;
}
}
}
function countComponents(nodeCount, edges) {
const finder = new UnionFind(nodeCount);
for (const edge of edges) {
finder.union(edge[0], edge[1]);
}
const roots = new Set();
for (let node = 0; node < nodeCount; node += 1) {
roots.add(finder.find(node));
}
return roots.size;
}Walkthrough
Union each edge; distinct find roots after processing equals component count.
Invariant: DSU maintains partition of nodes into connected components.
Edge Cases
- No edges —
nisolated nodes - Complete connection — one component
Pitfalls
- Counting edges instead of unique roots
Similar Problems
- 547. Number of Provinces — same task on adjacency matrix form
- 261. Graph Valid Tree — tree-specific constraints
Variants
- Dynamic edges (online) — still DSU
Mind-Map Tags
#union-find #components #undirected #connectivity
Last updated on
Spotted something unclear or wrong on this page?