Adjacency List Representation in DSA Typescript - Time & Space Complexity
We want to understand how fast we can access and traverse a graph stored as an adjacency list.
How does the time to visit nodes and edges grow as the graph gets bigger?
Analyze the time complexity of the following code snippet.
// Traverse all nodes and their neighbors in an adjacency list
function traverseGraph(adjList: Map<number, number[]>) {
for (const node of adjList.keys()) {
const neighbors = adjList.get(node) || [];
for (const neighbor of neighbors) {
// process edge from node to neighbor
}
}
}
This code visits every node and then visits each neighbor connected to that node.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The nested loops: outer loop over all nodes, inner loop over each node's neighbors.
- How many times: Outer loop runs once per node (n times), inner loop runs once per edge connected to that node.
As the graph grows, the number of nodes (n) and edges (e) increase.
| Input Size (n nodes, e edges) | Approx. Operations |
|---|---|
| 10 nodes, 15 edges | About 10 (nodes) + 15 (edges) = 25 operations |
| 100 nodes, 200 edges | About 100 + 200 = 300 operations |
| 1000 nodes, 5000 edges | About 1000 + 5000 = 6000 operations |
Pattern observation: The total work grows roughly with the sum of nodes and edges.
Time Complexity: O(n + e)
This means the time to traverse depends on how many nodes and edges the graph has combined.
[X] Wrong: "Traversal time is just O(n) because we visit each node once."
[OK] Correct: We also visit all edges connected to nodes, so edges add to the total work and cannot be ignored.
Understanding adjacency list traversal time helps you explain graph algorithms clearly and shows you know how data size affects performance.
"What if the graph was stored as an adjacency matrix instead? How would the time complexity change?"
Practice
Solution
Step 1: Understand adjacency list concept
An adjacency list stores each node with a list of its neighbors, showing direct connections.Step 2: Compare options with definition
Only A list where each node stores its connected neighbors correctly describes this structure; others describe different concepts.Final Answer:
A list where each node stores its connected neighbors -> Option DQuick Check:
Adjacency list = neighbors list [OK]
- Confusing adjacency list with adjacency matrix
- Thinking it stores distances instead of neighbors
- Assuming it is a queue or unrelated structure
Solution
Step 1: Identify adjacency list type
An adjacency list maps each node (number) to an array of connected nodes (number[]).Step 2: Match TypeScript syntax
Map correctly represents this; others are incorrect types or structures.Final Answer:
const graph: Map = new Map(); -> Option BQuick Check:
Map = adjacency list [OK]
- Using Record which maps to single number, not array
- Using number[][] without keys for nodes
- Using Array<number> which is just a list, not adjacency
const graph: Map = new Map(); graph.set(1, [2, 3]); graph.set(2, [1]); graph.set(3, [1, 4]); graph.set(4, [3]); console.log(graph.get(3));
Solution
Step 1: Trace graph.set calls
Node 3 is set with neighbors [1, 4].Step 2: Check graph.get(3)
Returns the array [1, 4] assigned to node 3.Final Answer:
[1, 4] -> Option CQuick Check:
graph.get(3) = [1, 4] [OK]
- Confusing neighbors of node 3 with node 1 or 2
- Expecting undefined if not careful with set calls
- Mixing up array contents order
const graph: Map = new Map(); graph.set(1, [2]); graph.set(2, [1]); graph.get(3).push(1);
Solution
Step 1: Check graph.get(3) call
Node 3 was never set, so graph.get(3) returns undefined.Step 2: Understand push on undefined
Calling push on undefined causes runtime error.Final Answer:
graph.get(3) returns undefined, so push causes error -> Option AQuick Check:
Accessing unset key returns undefined [OK]
- Assuming graph.get(3) returns empty array automatically
- Thinking Map keys must be strings (numbers are allowed)
- Ignoring runtime error from push on undefined
const graph: Map = new Map(); graph.set(1, [2]); graph.set(2, [3]); graph.set(3, []); graph.set(4, []); // Add edge from 2 to 4 here
Solution
Step 1: Understand existing edges
Node 2 currently has neighbors [3]. We want to add 4 without removing 3.Step 2: Choose correct method to add edge
Using graph.get(2)?.push(4) adds 4 to existing array, preserving [3]. graph.set(2, [4]) replaces neighbors, removing 3.Final Answer:
graph.get(2)?.push(4); -> Option AQuick Check:
Use push to add edge without overwriting [OK]
- Overwriting neighbors array with set instead of pushing
- Adding edge to wrong node
- Confusing direction of edge in directed graph
Ready to prove it?
Pass the test and this pattern moves unknown
