Adjacency List Representation in DSA Java - Time & Space Complexity
We want to understand how fast operations run when using adjacency lists to represent graphs.
Specifically, how the time to access or traverse connections changes as the graph grows.
Analyze the time complexity of the following code snippet.
// Adding edges to an adjacency list for a graph
List<List<Integer>> adjList = new ArrayList<>();
for (int i = 0; i < n; i++) {
adjList.add(new ArrayList<>());
}
// Add edge from u to v
adjList.get(u).add(v);
This code creates an adjacency list for a graph with n vertices and adds an edge from vertex u to vertex v.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Loop runs n times to create empty lists for each vertex.
- How many times: Exactly n times for initialization; adding an edge is a single operation.
As the number of vertices n grows, creating the adjacency list takes time proportional to n.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 (creating 10 lists) |
| 100 | 100 (creating 100 lists) |
| 1000 | 1000 (creating 1000 lists) |
Pattern observation: The time grows linearly with the number of vertices.
Time Complexity: O(n)
This means the time to set up the adjacency list grows directly with the number of vertices.
[X] Wrong: "Adding an edge takes O(n) time because we have to search the list."
[OK] Correct: Adding an edge is just appending to a list, which is O(1) on average, not searching.
Understanding adjacency lists helps you explain graph storage clearly and analyze graph algorithms efficiently.
"What if we used an adjacency matrix instead? How would the time complexity for adding edges change?"
Practice
Solution
Step 1: Understand adjacency list concept
An adjacency list stores each vertex with a list of vertices it connects to directly.Step 2: Compare with other graph representations
Unlike adjacency matrix, adjacency list focuses on neighbors per vertex, not all pairs.Final Answer:
A list where each vertex stores a list of its adjacent vertices -> Option AQuick Check:
Adjacency list = vertex with neighbors [OK]
- Confusing adjacency list with adjacency matrix
- Thinking it stores edges only without vertices
- Assuming it stores isolated vertices only
Solution
Step 1: Understand adjacency list declaration
We need an array of ArrayLists, one for each vertex, so ArrayList<Integer>[] is correct.Step 2: Check syntax correctness
ArrayList<Integer>[] graph = new ArrayList[5]; correctly declares an array of ArrayLists with size 5. Others misuse generics or types.Final Answer:
ArrayList<Integer>[] graph = new ArrayList[5]; -> Option AQuick Check:
Array of ArrayLists = ArrayList<Integer>[] graph = new ArrayList[5]; [OK]
- Using List instead of ArrayList for array declaration
- Trying to instantiate generic arrays directly
- Missing generic type in ArrayList declaration
ArrayList<Integer>[] graph = new ArrayList[3]; for (int i = 0; i < 3; i++) graph[i] = new ArrayList<>(); graph[0].add(1); graph[1].add(0); graph[1].add(2); graph[2].add(1); System.out.println(graph[1]);
Solution
Step 1: Trace additions to graph[1]
graph[1] adds 0 and 2, so its list contains [0, 2].Step 2: Confirm output of System.out.println(graph[1])
Printing graph[1] shows the list [0, 2].Final Answer:
[0, 2] -> Option DQuick Check:
graph[1] = [0, 2] [OK]
- Confusing indices and values in adjacency list
- Forgetting undirected edges require adding both ways
- Misreading the printed list order
ArrayList<Integer>[] graph = new ArrayList[4];
for (int i = 0; i <= 4; i++) {
graph[i] = new ArrayList<>();
}Solution
Step 1: Analyze loop range and array size
Array size is 4, valid indices are 0 to 3. Loop uses i <= 4, which accesses index 4 (out of bounds).Step 2: Identify correct loop condition
Loop should run while i < 4 to avoid ArrayIndexOutOfBoundsException.Final Answer:
Loop condition should be i < 4, not i <= 4 -> Option CQuick Check:
Array indices 0 to 3, loop must use i < 4 [OK]
- Using <= instead of < in loop condition
- Assuming array size 4 means indices 0 to 4
- Ignoring generic type warnings
Solution
Step 1: Understand weighted directed graph needs
Each edge has a destination vertex and a weight value, so both must be stored.Step 2: Choose data structure to store pairs
Using ArrayList of Pair allows storing destination and weight together.Step 3: Evaluate other options
ArrayList<Integer> storing only destination vertices stores only destination, missing weight; ArrayList storing all edges as lists is nested lists without clear pair; ArrayList<Boolean> storing if edge exists or not stores booleans, not weights.Final Answer:
ArrayList> storing destination and weight -> Option BQuick Check:
Weighted edges need destination + weight pairs [OK]
- Storing only destination without weight
- Using nested lists without clear structure
- Using booleans which can't hold weights
Ready to prove it?
Pass the test and this pattern moves unknown
