Graphs — Representations & Fundamentals

0/12 in this phase0/57 across the roadmap

šŸ“– Concept

A graph is a collection of nodes (vertices) connected by edges. Graphs model relationships: social networks, maps, dependencies, state machines.

Graph types:

  • Directed vs Undirected: One-way or two-way edges
  • Weighted vs Unweighted: Edges have costs or all equal
  • Cyclic vs Acyclic: Contains cycles or not (DAG = Directed Acyclic Graph)
  • Dense vs Sparse: Many edges (|E| ā‰ˆ |V|²) or few (|E| ā‰ˆ |V|)

Representations:

  1. Adjacency List: Array/Map of lists — O(V + E) space. Best for sparse graphs.
  2. Adjacency Matrix: 2D array — O(V²) space. Best for dense graphs, quick edge lookup.
  3. Edge List: Array of [from, to, weight] — simple but slow lookup.

Key algorithms:

  • BFS: Level-by-level, shortest path in unweighted, O(V + E)
  • DFS: Go deep, detect cycles, topological sort, O(V + E)
  • Dijkstra: Shortest path, weighted (no negative), O((V+E) log V)
  • Topological Sort: Order tasks with dependencies (DAG only)
  • Union-Find: Connected components, cycle detection

šŸ  Real-world analogy: A city map. Intersections are vertices, roads are edges. One-way streets = directed. Road lengths = weights. Finding shortest route = Dijkstra. Finding if two cities are connected = BFS/DFS.

šŸ’» Code Example

codeTap to expand ā›¶
1// GRAPH REPRESENTATIONS
2
3// ADJACENCY LIST (most common)
4function buildAdjList(n, edges) {
5 const graph = new Map();
6 for (let i = 0; i < n; i++) graph.set(i, []);
7 for (const [from, to] of edges) {
8 graph.get(from).push(to);
9 graph.get(to).push(from); // Undirected
10 }
11 return graph;
12}
13
14// ADJACENCY MATRIX
15function buildAdjMatrix(n, edges) {
16 const matrix = Array.from({length: n}, () => new Array(n).fill(0));
17 for (const [from, to, weight = 1] of edges) {
18 matrix[from][to] = weight;
19 matrix[to][from] = weight; // Undirected
20 }
21 return matrix;
22}
23
24// BFS — O(V + E)
25function bfs(graph, start) {
26 const visited = new Set([start]);
27 const queue = [start];
28 const order = [];
29 while (queue.length) {
30 const node = queue.shift();
31 order.push(node);
32 for (const neighbor of graph.get(node) || []) {
33 if (!visited.has(neighbor)) {
34 visited.add(neighbor);
35 queue.push(neighbor);
36 }
37 }
38 }
39 return order;
40}
41
42// DFS — O(V + E)
43function dfs(graph, start) {
44 const visited = new Set();
45 const order = [];
46 function explore(node) {
47 visited.add(node);
48 order.push(node);
49 for (const neighbor of graph.get(node) || []) {
50 if (!visited.has(neighbor)) explore(neighbor);
51 }
52 }
53 explore(start);
54 return order;
55}
56
57// SHORTEST PATH — BFS (unweighted)
58function shortestPath(graph, start, end) {
59 const visited = new Set([start]);
60 const queue = [[start, 0]];
61 while (queue.length) {
62 const [node, dist] = queue.shift();
63 if (node === end) return dist;
64 for (const neighbor of graph.get(node) || []) {
65 if (!visited.has(neighbor)) {
66 visited.add(neighbor);
67 queue.push([neighbor, dist + 1]);
68 }
69 }
70 }
71 return -1; // Not reachable
72}
73
74// COUNT CONNECTED COMPONENTS
75function countComponents(n, edges) {
76 const graph = buildAdjList(n, edges);
77 const visited = new Set();
78 let count = 0;
79 for (let i = 0; i < n; i++) {
80 if (!visited.has(i)) {
81 bfsVisit(graph, i, visited);
82 count++;
83 }
84 }
85 return count;
86}
87
88function bfsVisit(graph, start, visited) {
89 const queue = [start];
90 visited.add(start);
91 while (queue.length) {
92 const node = queue.shift();
93 for (const neighbor of graph.get(node) || []) {
94 if (!visited.has(neighbor)) {
95 visited.add(neighbor);
96 queue.push(neighbor);
97 }
98 }
99 }
100}

šŸ‹ļø Practice Exercise

Practice Problems (Easy → Hard):

  1. Build a graph from edge list using adjacency list
  2. BFS traversal — print all nodes level by level
  3. DFS traversal — recursive and iterative
  4. Find if a path exists between two nodes
  5. Count connected components in an undirected graph
  6. Detect a cycle in an undirected graph
  7. Detect a cycle in a directed graph
  8. Clone a graph (deep copy)
  9. Find all paths from source to target (DAG)
  10. Check if a graph is bipartite

āš ļø Common Mistakes

  • Forgetting the visited set — leads to infinite loops in cyclic graphs

  • Using BFS for weighted shortest path — BFS only works for unweighted; use Dijkstra for weighted

  • Not handling disconnected graphs — BFS/DFS from one node may not reach all nodes

  • Confusing directed and undirected edge addition — undirected adds both directions

  • Using adjacency matrix for sparse graphs — wastes O(V²) space when O(V+E) suffices

šŸ’¼ Interview Questions

šŸŽ¤ Mock Interview

Practice a live interview for Graphs — Representations & Fundamentals