Shortest Path in Unweighted Graph Using BFS in DSA Typescript - Time & Space Complexity
We want to understand how long it takes to find the shortest path in an unweighted graph using BFS.
Specifically, how the time grows as the graph gets bigger.
Analyze the time complexity of the following code snippet.
function shortestPathBFS(graph: Map<number, number[]>, start: number, end: number): number {
const queue: number[] = [start];
const visited = new Set<number>([start]);
let distance = 0;
while (queue.length > 0) {
const size = queue.length;
for (let i = 0; i < size; i++) {
const node = queue.shift()!;
if (node === end) return distance;
for (const neighbor of graph.get(node) || []) {
if (!visited.has(neighbor)) {
visited.add(neighbor);
queue.push(neighbor);
}
}
}
distance++;
}
return -1;
}
This code finds the shortest number of steps from start to end in an unweighted graph using BFS.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Visiting each node and checking its neighbors in the graph.
- How many times: Each node is visited once, and each edge is checked once during the BFS traversal.
As the graph grows, the BFS visits more nodes and edges.
| Input Size (n = nodes) | Approx. Operations (visiting nodes + edges) |
|---|---|
| 10 | About 10 nodes + edges checked |
| 100 | About 100 nodes + edges checked |
| 1000 | About 1000 nodes + edges checked |
Pattern observation: The work grows roughly in proportion to the number of nodes and edges.
Time Complexity: O(V + E)
This means the time grows linearly with the number of nodes (V) plus the number of edges (E) in the graph.
[X] Wrong: "BFS takes O(V²) time because it loops over nodes inside another loop."
[OK] Correct: BFS visits each node and edge only once, so it does not multiply visits. The inner loops run only for neighbors, not all nodes.
Understanding BFS time complexity helps you explain how graph searches scale and why BFS is efficient for shortest paths in unweighted graphs.
"What if the graph was represented as an adjacency matrix instead of adjacency lists? How would the time complexity change?"
Practice
Solution
Step 1: Understand BFS traversal
BFS explores nodes level by level starting from the source node.Step 2: BFS finds shortest paths in unweighted graphs
Because BFS visits nodes in order of increasing distance, it finds shortest paths.Final Answer:
The shortest path from a start node to all other nodes -> Option AQuick Check:
BFS = shortest path in unweighted graph [OK]
- Confusing BFS with DFS for shortest path
- Thinking BFS finds longest path
- Assuming BFS works for weighted graphs without modification
Solution
Step 1: Identify queue operations needed for BFS
BFS requires FIFO order: enqueue at end, dequeue from front.Step 2: Choose Array methods matching FIFO
push() adds to end, shift() removes from front, so Array with push() and shift() works as a queue.Final Answer:
Array with push() and shift() -> Option BQuick Check:
Queue = push + shift [OK]
- Using pop() instead of shift() causes LIFO behavior
- Using Set or Map which don't maintain order
- Using Array methods incorrectly for queue
const graph = [[1,2],[0,3],[0,3],[1,2]]; // Nodes: 0,1,2,3 // Edges: 0-1, 0-2, 1-3, 2-3
Solution
Step 1: Initialize distances and start BFS from node 0
Distance to 0 is 0, others infinity initially.Step 2: Visit neighbors level-wise
Neighbors of 0 are 1 and 2, set distance 1 for both. Then neighbors of 1 and 2 include 3, set distance 2 for 3.Final Answer:
[0, 1, 1, 2] -> Option AQuick Check:
Distances from 0 = [0,1,1,2] [OK]
- Mixing up node indices and distances
- Assigning wrong distances to neighbors
- Confusing BFS with DFS order
function bfs(graph: number[][], start: number) {
const queue = [];
const distances = Array(graph.length).fill(-1);
distances[start] = 0;
queue.push(start);
while (queue.length > 0) {
const node = queue.pop();
for (const neighbor of graph[node]) {
if (distances[neighbor] === -1) {
distances[neighbor] = distances[node] + 1;
queue.push(neighbor);
}
}
}
return distances;
}Solution
Step 1: Check queue operations in BFS
BFS requires FIFO queue, but pop() removes from end (LIFO).Step 2: Identify impact of pop() usage
Using pop() makes traversal DFS-like, breaking shortest path logic.Final Answer:
Using pop() instead of shift() causes wrong BFS order -> Option DQuick Check:
Queue must be FIFO: push + shift [OK]
- Confusing pop() with shift() for queue
- Ignoring visited check for neighbors
- Incorrect initialization of distances
Solution
Step 1: Explore neighbors from node 0
Neighbors are 1 and 2, both distance 1.Step 2: Explore neighbors of 1 and 2
Both connect to 3 at distance 2.Step 3: From 3, move to 4 at distance 3
Shortest path is 0 -> 1 -> 3 -> 4 or 0 -> 2 -> 3 -> 4.Step 4: Choose path found first by BFS
BFS visits 1 before 2, so path is [0,1,3,4].Final Answer:
[0, 1, 3, 4] -> Option CQuick Check:
Shortest path BFS = [0,1,3,4] [OK]
- Assuming direct edge from 0 to 4 exists
- Choosing longer path ignoring BFS order
- Confusing path with distance array
Ready to prove it?
Pass the test and this pattern moves unknown
