# Adjacency list (most common in interviews)
graph = {0: [1, 2], 1: [0, 3], 2: [0], 3: [1]}
# Build from edge listfrom collections import defaultdict
defbuild_graph(edges):
graph = defaultdict(list)
for u, v in edges:
graph[u].append(v)
graph[v].append(u) # remove for directedreturn graph
Pattern 1 — DFS (Recursive / Iterative)
defdfs(graph, node, visited):
visited.add(node)
for neighbor in graph[node]:
if neighbor notin visited:
dfs(graph, neighbor, visited)
Pattern 2 — BFS (Shortest Path in unweighted graph)
from collections import deque
defbfs(graph, start):
visited = {start}
queue = deque([start])
distance = {start: 0}
while queue:
node = queue.popleft()
for neighbor in graph[node]:
if neighbor notin visited:
visited.add(neighbor)
distance[neighbor] = distance[node] + 1
queue.append(neighbor)
return distance
Pattern 3 — Topological Sort (Kahn's Algorithm)
from collections import deque, defaultdict
deftopo_sort(n, prerequisites):
graph = defaultdict(list)
indegree = [0] * n
for course, pre in prerequisites:
graph[pre].append(course)
indegree[course] += 1
queue = deque([i for i inrange(n) if indegree[i] == 0])
order = []
while queue:
node = queue.popleft()
order.append(node)
for neighbor in graph[node]:
indegree[neighbor] -= 1if indegree[neighbor] == 0:
queue.append(neighbor)
return order iflen(order) == n else [] # empty = cycle exists