Connected Components Using BFS in DSA Java - Time & Space Complexity
We want to understand how long it takes to find connected parts in a graph using BFS.
How does the time grow as the graph gets bigger?
Analyze the time complexity of the following code snippet.
public int countConnectedComponents(int n, List> graph) {
boolean[] visited = new boolean[n];
int count = 0;
for (int i = 0; i < n; i++) {
if (!visited[i]) {
bfs(i, graph, visited);
count++;
}
}
return count;
}
private void bfs(int start, List> graph, boolean[] visited) {
Queue<Integer> queue = new LinkedList<>();
queue.add(start);
visited[start] = true;
while (!queue.isEmpty()) {
int node = queue.poll();
for (int neighbor : graph.get(node)) {
if (!visited[neighbor]) {
visited[neighbor] = true;
queue.add(neighbor);
}
}
}
}
This code counts how many separate groups of connected nodes exist in a graph using BFS.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: BFS visits each node and its edges once.
- How many times: Each node is visited once; each edge is checked once.
As the graph grows, BFS visits all nodes and edges once, so work grows with nodes plus edges.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 nodes, 15 edges | About 25 visits (10 nodes + 15 edges) |
| 100 nodes, 200 edges | About 300 visits (100 + 200) |
| 1000 nodes, 3000 edges | About 4000 visits (1000 + 3000) |
Pattern observation: The total work grows roughly with the sum of nodes and edges.
Time Complexity: O(n + e)
This means the time grows linearly with the number of nodes plus the number of edges in the graph.
[X] Wrong: "BFS runs in O(n²) because it has nested loops."
[OK] Correct: BFS visits each node and edge only once, so it does not repeat work for every pair of nodes.
Understanding BFS time helps you explain how graph searches scale, a key skill for many coding problems.
"What if the graph is represented as an adjacency matrix instead of adjacency lists? How would the time complexity change?"
Practice
Solution
Step 1: Understand BFS in graph context
BFS explores all nodes reachable from a given start node by visiting neighbors level by level.Step 2: Connect BFS to connected components
By running BFS from an unvisited node, we find all nodes in that node's connected component.Final Answer:
All nodes reachable from a starting node forming one connected component -> Option DQuick Check:
BFS finds connected components by exploring reachable nodes [OK]
- Thinking BFS only finds shortest paths
- Confusing connected components with edge count
- Assuming BFS finds node degrees
Solution
Step 1: Identify correct Queue implementation
Java's Queue interface is commonly implemented by LinkedList for BFS.Step 2: Check other options
ArrayList is not a Queue, Stack is LIFO not FIFO, HashSet is a Set, not a Queue.Final Answer:
Queue<Integer> queue = new LinkedList<>(); -> Option AQuick Check:
LinkedList implements Queue for BFS [OK]
- Using ArrayList instead of Queue
- Using Stack which is LIFO, not FIFO
- Using HashSet which is unordered
int n = 5;
List graph = new ArrayList<>();
for (int i = 0; i < n; i++) graph.add(new ArrayList<>());
graph.get(0).add(1);
graph.get(1).add(0);
graph.get(2).add(3);
graph.get(3).add(2);
boolean[] visited = new boolean[n];
int count = 0;
for (int i = 0; i < n; i++) {
if (!visited[i]) {
Queue<Integer> queue = new LinkedList<>();
queue.add(i);
visited[i] = true;
while (!queue.isEmpty()) {
int node = queue.poll();
for (int nei : graph.get(node)) {
if (!visited[nei]) {
visited[nei] = true;
queue.add(nei);
}
}
}
count++;
}
}
System.out.println(count);Solution
Step 1: Analyze graph edges
Edges connect nodes 0-1 and 2-3. Node 4 is isolated.Step 2: Count connected components
Components are {0,1}, {2,3}, and {4} -> total 3 components.Final Answer:
3 -> Option AQuick Check:
3 connected groups found [OK]
- Ignoring isolated nodes
- Counting edges instead of components
- Misreading graph connections
for (int i = 0; i < n; i++) {
if (!visited[i]) {
Queue<Integer> queue = new LinkedList<>();
queue.add(i);
while (!queue.isEmpty()) {
int node = queue.poll();
for (int nei : graph.get(node)) {
if (!visited[nei]) {
queue.add(nei);
visited[nei] = true;
}
}
}
count++;
}
}Solution
Step 1: Check visited marking
visited[i] should be set true when node i is added to queue to avoid revisiting.Step 2: Identify missing visited update
Code adds i to queue but does not mark visited[i] true before BFS loop.Final Answer:
visited[i] is not set to true before BFS -> Option BQuick Check:
Mark visited when adding to queue [OK]
- Marking visited after dequeueing
- Not initializing queue correctly
- Incrementing count inside BFS loop
Solution
Step 1: Identify connected groups
Edges form groups: {0,1,2}, {3,4}, {5,6} -- total 3 components (nodes 0-6).Step 2: Count components and largest group
3 components total. Largest is {0,1,2} with 3 nodes.Final Answer:
3 connected components; largest component nodes: [0, 1, 2] -> Option CQuick Check:
3 components, largest size 3 [OK]
- Counting nodes incorrectly
- Missing isolated nodes
- Mixing node indices
Ready to prove it?
Pass the test and this pattern moves unknown
