Pattern #47
Graphs
Important interview questions, thinking patterns, Adjacency List setup, Visited Set rules, Unweighted BFS shortest paths, Grid-to-Graph conversion, and Go templates.
Must Solve
20 core questions — solve these first.
- 1.Number of IslandsGrid as Graph: Connected Components count using DFS/BFS marking land "0"medium
- 2.Clone GraphDFS/BFS + HashMap mapping original node -> copied node to prevent duplicate cloning in cyclesmedium
- 3.Number of ProvincesConnected Components in Adjacency Matrix using visited array + DFSmedium
- 4.Flood FillGrid DFS changing matching initial color cells to new coloreasy
- 5.Rotting OrangesMulti-Source BFS: enqueue all rotten oranges at minute 0 and spread in parallel wavesmedium
- 6.Course ScheduleDirected Cycle Detection (0=unvisited, 1=visiting, 2=finished) or Topological Sortmedium
- 7.Course Schedule IITopological Sort (Kahn's BFS or DFS postorder reversed) returning valid orderingmedium
- 8.Pacific Atlantic Water FlowReverse Multi-Source BFS/DFS starting from ocean boundaries inwardmedium
- 9.Surrounded RegionsBoundary DFS: mark border-connected "O"s as safe, capture remaining "O"s to "X"medium
- 10.Max Area of IslandGrid DFS returning 1 + sum(dfs(neighbor)) for each connected land massmedium
- 11.Graph Valid TreeCheck edges == n - 1 AND graph is fully connected without cyclesmedium
- 12.Redundant ConnectionUnion Find / Disjoint Set: find first edge where find(u) == find(v)medium
- 13.Is Graph Bipartite?BFS/DFS 2-coloring: if neighbor has same color -> return falsemedium
- 14.Word LadderUnweighted Shortest Path BFS: transform word 1 char at a time checking dictionary sethard
- 15.Open the LockBFS level-by-level distance rings starting from "0000" avoiding deadendsmedium
- 16.Evaluate DivisionWeighted Directed Graph: DFS to find product of path weights A -> Bmedium
- 17.Reorder Routes to Make All Paths Lead to ZeroTree DFS from 0 tracking artificial forward edges vs original reverse edgesmedium
- 18.Shortest Path in Binary Matrix8-directional BFS in binary grid from (0,0) to (n-1, n-1)medium
- 19.Network Delay TimeDijkstra's algorithm with Priority Queue for weighted shortest pathmedium
- 20.Cheapest Flights Within K StopsBellman-Ford / Modified BFS with stop constraint arraymedium
Also Important
10 more questions worth practicing.
- 21.Accounts MergeUnion Find connecting emails belonging to same personmedium
- 22.Alien DictionaryConstruct character dependency graph from adjacent words + Topological Sorthard
- 23.Minimum Height TreesKahn's leaf-trimming BFS until 1 or 2 center nodes remainmedium
- 24.Find Eventual Safe StatesReverse graph + Topological Sort / DFS 3-state cycle detectionmedium
- 25.Keys and RoomsGraph reachability BFS/DFS tracking visited rooms starting from room 0medium
- 26.Possible BipartitionConstruct dislike graph + BFS/DFS 2-coloringmedium
- 27.All Paths From Source to TargetDAG DFS + Backtracking appending path from 0 to n-1medium
- 28.Detonate the Maximum BombsDirected graph where edge u -> v exists if dist(u, v) <= radius(u); run DFS from each bombmedium
- 29.Find Closest Node to Given Two NodesRun 2 BFS passes from node1 and node2 to compute distance arraysmedium
- 30.Minimum Genetic MutationBFS gene mutation string transformation in bank setmedium
How to Think
- Things are connected to other things?Graph (Nodes & Edges)
- Need explore connected area?DFS / BFS + Visited Set
- Need count groups?Connected Components
- Need shortest path with every edge same cost?BFS (Level-by-level rings)
- Need detect cycle?DFS 3-state / Union Find
- Dependencies / prerequisites?Directed Graph + Topological Sort
- Weighted shortest path?Dijkstra (non-negative weights)
Go Graph Code Templates
Graph DFS & Unweighted Shortest Path BFS in Go
// 1. Graph DFS (Adjacency List + Visited Set)
func graphDFS(n int, edges [][]int) {
adj := make([][]int, n)
for _, e := range edges {
u, v := e[0], e[1]
adj[u] = append(adj[u], v)
adj[v] = append(adj[v], u) // Undirected: Add both!
}
visited := make([]bool, n)
var dfs func(u int)
dfs = func(u int) {
visited[u] = true
for _, neighbor := range adj[u] {
if !visited[neighbor] {
dfs(neighbor)
}
}
}
for i := 0; i < n; i++ {
if !visited[i] {
dfs(i) // Discover each connected component
}
}
}
// 2. Unweighted Shortest Path BFS (Mark visited WHEN ENQUEUED!)
func shortestPathBFS(n int, edges [][]int, start, target int) int {
adj := make([][]int, n)
for _, e := range edges {
u, v := e[0], e[1]
adj[u] = append(adj[u], v)
adj[v] = append(adj[v], u)
}
visited := make([]bool, n)
queue := []int{start}
visited[start] = true // Mark when enqueued!
dist := 0
for len(queue) > 0 {
size := len(queue)
for i := 0; i < size; i++ {
curr := queue[0]
queue = queue[1:]
if curr == target {
return dist
}
for _, neighbor := range adj[curr] {
if !visited[neighbor] {
visited[neighbor] = true // Mark when enqueued!
queue = append(queue, neighbor)
}
}
}
dist++
}
return -1
}👉 Total Time: O(V + E) | Space: O(V + E)
Visited Set & Mandatory BFS Enqueue Rule
1. Visited Set is Mandatory: Unlike Trees (which are acyclic), Graphs can contain cycles (A -> B -> C -> A). Without a visited set, graph traversals enter infinite loops!
2. Mark Visited When ENQUEUED: In BFS, always mark visited[neighbor] = true as soon as you append the node to the queue! If you mark it when popping, the same node will be inserted into the queue multiple times by adjacent neighbors, exploding queue size.
Grid as Graph & Multi-Source BFS
1. Grid as Graph: Many matrix problems (Number of Islands, Flood Fill, Surrounded Regions) are secretly Graph problems! Each cell grid[r][c] is a node, and valid 4-directional adjacent cells are edges.
2. Multi-Source BFS: When expansion starts from multiple starting points at once (Rotting Oranges, Pacific Atlantic Water Flow), push ALL initial sources into the queue simultaneously at minute 0, then expand BFS in parallel waves!
Graph → Nodes + Edges (May contain cycles & disconnected components)
Visited Set → MANDATORY to prevent infinite loops (Mark WHEN ENQUEUED in BFS!)
Unweighted Path → BFS guaranteed shortest distance in level-by-level rings
Multi-Source BFS → Push ALL initial sources into queue at minute 0 simultaneously
Shortest Path → Unweighted (BFS) | Non-negative (Dijkstra) | Negative (Bellman-Ford)💡 Golden Rule: "Turn the problem into ‘What are the nodes, what are the edges, and how should I explore the neighbors?’"
Common Interview Mistakes
Omitting the visited set in a graph with cycles causes infinite recursion / stack overflow crashes!
In BFS, always mark visited[neighbor] = true when enqueuing! Marking when popping allows duplicate queue entries.
For directed edges (u -> v), only add v to adj[u]. Do NOT add u to adj[v]!
Standard BFS only guarantees shortest path when all edge costs are equal (unweighted)! Weighted graphs require Dijkstra\'s algorithm.
Interview Rules
- 1. Things connected to other things?→ Graph (Nodes & Edges)
- 2. Explore connected area? → DFS / BFS + Visited Set
- 3. Count connected components?→ Loop over all nodes; if unvisited, increment count & run DFS/BFS
- 4. Unweighted shortest path? → BFS (Level-by-level distance rings)
- 5. Prerequisites / Dependencies? → Directed Graph + Topological Sort
- 6. Multi-Source expansion (Rotting Oranges)? → Push ALL initial sources into queue at minute 0
- 7. Weighted shortest path? → Dijkstra (non-negative weights) | Bellman-Ford (negative weights)
- 8. Overall Complexity → Time:
O(V + E)| Space:O(V + E)
Small Rules
- Rule 1: Graphs consist of Nodes (entities) and Edges (connections).
- Rule 2: Visited set is mandatory to prevent infinite loops in cyclic graphs.
- Rule 3: Unweighted shortest path is always solved using BFS.
- Rule 4: Mark nodes as visited WHEN ENQUEUED in BFS.
- Rule 5: Matrix connected cell problems are Graph problems in disguise.
Production Thinking
Social Network Friend Graphs → Determining degrees of separation & mutual friend recommendations
Microservice Dependency Graphs → Detecting circular service dependencies (Auth -> Orders -> Payments -> Auth)
Road Network Navigation → Calculating shortest driving routes & travel times using weighted graph routing
Build System Package Resolution → Determining correct package compilation order using Topological Sort
Remember This
Graph → Nodes + Edges
DFS → Go deep
BFS → Level by level
Visited → Prevent repeats & cycles
Components → Count groups
Shortest Path → BFS (unweighted)
Multi-Source BFS → All starts at once
Dependencies → Directed Graph
Weighted Path → Dijkstra
Time → O(V + E)💡 Golden Rule: "Turn the problem into ‘What are the nodes, what are the edges, and how should I explore the neighbors?’"