The single question that drives the choice: "What do I ask most often?"
u and v?" → matrix (O(1) lookup).u's neighbors?" → adjacency list (iterate only real edges).Each node stores a list of its neighbors. For n nodes you keep n lists.
This is what you'll use in ~90% of interview problems because most graphs are sparse
(edges ≪ n²).
An n × n grid where matrix[u][v] = 1 (or the weight)
if an edge exists. Instant edge lookups, but costs O(n²) space even if the graph has 3 edges.
Great for dense graphs or Floyd-Warshall (Week 2).
Just a list of (u, v, weight) triples. Minimal, and perfect when the
algorithm processes edges directly (Kruskal's, Bellman-Ford).
u→v and v→u). Forgetting this is the #1 beginner bug.u→v.int[]{v, w} or a small class).| Representation | Space | Edge lookup | Iterate neighbors | Best for |
|---|---|---|---|---|
| Adjacency List | O(V + E) | O(deg) | O(deg) — optimal | Sparse graphs (default) |
| Adjacency Matrix | O(V²) | O(1) | O(V) | Dense graphs, Floyd-Warshall |
| Edge List | O(E) | O(E) | O(E) | Kruskal, Bellman-Ford |
A flexible Graph class backed by an adjacency list, supporting directed/undirected and weighted edges.
import java.util.*;
/** Weighted adjacency-list graph. Set weighted=false to ignore weights. */
public class Graph {
private final int n;
private final boolean directed;
private final List<int[]>[] adj; // adj[u] = list of {neighbor, weight}
public Graph(int n, boolean directed) {
this.n = n;
this.directed = directed;
adj = new List[n];
for (int i = 0; i < n; i++) adj[i] = new ArrayList<>();
}
public void addEdge(int u, int v, int w) {
adj[u].add(new int[]{v, w});
if (!directed) adj[v].add(new int[]{u, w}); // undirected → both ways
}
public void addEdge(int u, int v) { addEdge(u, v, 1); } // unweighted default
public List<int[]> neighbors(int u) { return adj[u]; }
public int size() { return n; }
}
// --- Adjacency matrix, when you need O(1) edge lookups ---
int[][] matrix = new int[n][n];
matrix[u][v] = w; // directed
// matrix[v][u] = w; // add this line for undirected
u→v but not v→u. Half your traversal silently breaks.n+1 or subtract 1 consistently.Representation is rarely the whole question, but the right choice quietly decides whether you pass or TLE. Interviewers probe it via:
| Disguise / phrasing | What's really tested | Twist to handle |
|---|---|---|
| "n up to 10⁵, edges sparse" | Will you pick a list over a matrix? | Matrix = 10¹⁰ cells → MLE. Must use adjacency list |
| "Frequent 'is there an edge u–v?' queries" | O(1) lookup need | Adjacency matrix or a HashSet of edges |
| "Grid / maze / islands" | Implicit graph recognition | Cells = nodes, 4/8-dir = edges; don't build explicit graph |
| "Edges given as a list, process by weight" | Edge-list fit | Keep as edge list (Kruskal, Bellman-Ford) |
| "Nodes labeled 1..n" / string node IDs | Indexing hygiene | Size arrays n+1, or map strings → ints consistently |
| "Convert / model this real-world thing as a graph" | Modeling skill | Identify what's a node vs an edge before coding |