Skip to main content

Number of Connected Components in an Undirected Graph - Solution & Explanation

MediumPremiumFree on FleetCodeDepth-First SearchBreadth-First SearchUnion FindGraph19 min readAsked at: Amazon, Meta, General Motors +4
Practice this problem

Problem Statement

You have a graph of n nodes. You are given an integer n and an array edges where edges[i] = [ai, bi] indicates that there is an edge between ai and bi in the graph.

Return the number of connected components in the graph.

 

Example 1:

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

Example 2:

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

 

Constraints:

  • 1 <= n <= 2000
  • 1 <= edges.length <= 5000
  • edges[i].length == 2
  • 0 <= ai <= bi < n
  • ai != bi
  • There are no repeated edges.

Approach Overview

Problem Overview: You are given n nodes labeled from 0 to n-1 and a list of undirected edges. The task is to determine how many connected components exist in the graph. A connected component is a group of nodes where every node is reachable from any other node in that group.

Approach 1: Graph Traversal using DFS/BFS (O(n + m) time, O(n + m) space)

Build an adjacency list from the edge list, then traverse the graph. Iterate through every node. If a node has not been visited, start a traversal (either Depth-First Search or Breadth-First Search) from that node and mark all reachable nodes as visited. Each time you start a new traversal, you have discovered a new connected component. The adjacency list takes O(n + m) space where m is the number of edges. The traversal visits each node and edge once, giving O(n + m) time complexity. This approach works well when you already represent the graph explicitly and want a clear traversal-based solution.

Approach 2: Union-Find / Disjoint Set (O(n + m · α(n)) time, O(n) space)

The Union-Find data structure groups nodes into sets representing components. Initially, every node is its own parent. For each edge (u, v), perform a union(u, v) operation to merge their sets. Use path compression and union by rank to keep the structure shallow. After processing all edges, the number of distinct roots equals the number of connected components. The amortized cost of each operation is nearly constant, α(n) (inverse Ackermann function). This approach avoids building adjacency lists and is particularly efficient when edges arrive incrementally or when solving multiple connectivity queries.

Both strategies rely on the same insight: nodes belong to the same component if there exists a path between them in the graph. Traversal explicitly explores that path structure, while Union-Find tracks connectivity through set merges.

Recommended for interviews: DFS or BFS traversal is the most commonly expected solution because it demonstrates understanding of graph representation and traversal. Union-Find is also highly valued since it shows familiarity with a powerful connectivity data structure. A candidate who can explain both approaches and their tradeoffs shows strong graph fundamentals.

Approach 1: DFS

First, we construct an adjacency list g based on the given edges, where g[i] represents all neighbor nodes of node i.

Then we traverse all nodes. For each node, we use DFS to traverse all its adjacent nodes and mark them as visited until all its adjacent nodes have been visited. In this way, we have found a connected component, and the answer is incremented by one. Then we continue to traverse the next unvisited node until all nodes have been visited.

The time complexity is O(n + m), and the space complexity is O(n + m). Where n and m are the number of nodes and edges, respectively.

Code

Python

Java

C++

Go

TypeScript

JavaScript

Try this approach in the editor →

Approach 2: Union-Find

We can use a union-find set to maintain the connected components in the graph.

First, we initialize a union-find set, then traverse all the edges. For each edge (a, b), we merge nodes a and b into the same connected component. If the merge is successful, it means that nodes a and b were not in the same connected component before, and the number of connected components decreases by one.

Finally, we return the number of connected components.

The time complexity is O(n + m times \alpha(n)), and the space complexity is O(n). Where n and m are the number of nodes and edges, respectively, and \alpha(n) is the inverse of the Ackermann function, which can be regarded as a very small constant.

Code

Python

Java

C++

Go

TypeScript

Try this approach in the editor →

Approach 3: BFS

We can also use BFS (Breadth-First Search) to count the number of connected components in the graph.

Similar to Solution 1, we first construct an adjacency list g based on the given edges. Then we traverse all nodes. For each node, if it has not been visited, we start BFS traversal from this node, marking all its adjacent nodes as visited, until all its adjacent nodes have been visited. In this way, we have found a connected component, and the answer is incremented by one.

After traversing all nodes, we get the number of connected components in the graph.

The time complexity is O(n + m), and the space complexity is O(n + m). Where n and m are the number of nodes and edges, respectively.

Code

Python

Java

C++

Go

TypeScript

Try this approach in the editor →

Complexity Comparison

ApproachComplexity
DFS
Union-Find
BFS

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
DFS/BFS Graph TraversalO(n + m)O(n + m)General graph problems when adjacency lists are easy to build and you want explicit traversal
Union-Find (Disjoint Set)O(n + m · α(n))O(n)Connectivity problems, dynamic edge additions, or when avoiding adjacency lists

Video Solution

Number of Connected Components in an Undirected Graph - Union Find - Leetcode 323 - PythonNeetCode270,776 views views

Watch 9 more video solutions →

Frequently Asked Questions

Is Number of Connected Components in an Undirected Graph easy or hard?
The problem is rated Medium because it requires understanding graph representation and traversal. The algorithm itself is straightforward once you know DFS/BFS or Union-Find, but recognizing that each traversal corresponds to one connected component is the key insight.
Number of Connected Components in an Undirected Graph Python/Java solution
The Python and Java solutions typically build an adjacency list using lists or hash maps and run DFS to mark reachable nodes. Each unvisited node starts a new traversal, incrementing the component count. The same logic translates easily across Python, Java, C++, Go, and JavaScript with O(n + m) complexity.
How to solve Number of Connected Components in an Undirected Graph in O(n)?
Strict O(n) is only possible when the number of edges is proportional to nodes. In general graphs the correct bound is O(n + m). Build an adjacency list and run DFS or BFS from each unvisited node, marking reachable nodes. The number of times you start a new traversal equals the number of connected components.
What is the best approach for Number of Connected Components in an Undirected Graph?
Depth-First Search (DFS) or Breadth-First Search (BFS) traversal is the most straightforward approach. Build an adjacency list and start a traversal from every unvisited node, counting each traversal as a new component. This runs in O(n + m) time where n is the number of nodes and m is the number of edges. Union-Find is another strong alternative, especially for dynamic connectivity problems.
Is Number of Connected Components in an Undirected Graph asked at Google/Amazon/Meta?
Graph connectivity problems appear frequently in interviews at companies such as Google, Amazon, Meta, and Microsoft. This problem specifically tests graph traversal and Union-Find fundamentals, which are common building blocks in larger system and graph problems.
What data structure is used in Number of Connected Components in an Undirected Graph?
Typical solutions use an adjacency list to represent the graph along with a visited array or set for DFS/BFS traversal. Another common structure is the Union-Find (Disjoint Set Union) data structure that maintains parent pointers and ranks to efficiently merge connected nodes.
What is the time complexity of Number of Connected Components in an Undirected Graph?
The optimal complexity is O(n + m) using DFS or BFS traversal because each node and edge is visited once. Using Union-Find with path compression and union by rank gives O(n + m · α(n)), where α(n) is the inverse Ackermann function and behaves almost like a constant in practice.

Ready to solve this problem?

Practice Number of Connected Components in an Undirected Graph with our built-in code editor and test cases.

Practice on FleetCode