Home / Patterns / Graphs

Graphs Pattern Hub

11 problems

Clone Graph

medium
TC: O(V + E) · SC: O(V)

Maintain `clones = { origNode: newNode }` *before* recursing into neighbors so cycles short-circuit immediately to the already allocated copy without infinite loops.

Course Schedule

medium
TC: O(V + E) · SC: O(V + E)

Kahn’s algorithm: track `indegree[v]` and push all `0`-indegree vertices into a queue. Repeatedly pop `u`, decrement neighbors’ indegrees, enqueue newly zeroed vertices, and verify `visited == numCourses`.

Course Schedule II

medium
TC: O(V + E) · SC: O(V + E)

Same Kahn’s topological sort as Course Schedule, collecting each dequeued vertex into `order`. Return `order` iff `len(order) == numCourses`, else `[]`.

Graph Valid Tree

medium
TC: O(N * a(N)) · SC: O(N)

Graph theorem: an undirected graph on `n` vertices is a tree iff `len(edges) == n - 1` AND union-find joins all edges without ever seeing an internal cycle (`find(u) == find(v)`).

Longest Increasing Path in a Matrix

hard
TC: O(M * N) · SC: O(M * N)

Strictly increasing edges `matrix[nr][nc] > matrix[r][c]` guarantee the implicit graph is a **DAG** (no cycles are possible!). Therefore no `visited` set is needed — plain memoized DFS (`cache[r][c]`) computes every cell’s longest path once.

Max Area of Island

medium
TC: O(M * N) · SC: O(M * N)

DFS returns exact area contributed by a connected component (`1 + sum(4 neighbors)`), sinking `1 -> 0` upon arrival so each cell counts once.

Number of Connected Components in an Undirected Graph

medium
TC: O(V + E * a(V)) · SC: O(V)

Disjoint Set Union (DSU) with path compression + union-by-rank/size: initialize `components = n`, decrement `components` on every successful union between distinct roots.

Number of Islands

medium
TC: O(M * N) · SC: O(M * N)

Iterate every cell `(r, c)`. Whenever `grid[r][c] == "1"`, increment `islands` and immediately flood-fill (DFS/BFS) all 4-connected `"1"` cells to `"0"` in-place so each component is counted once.

Pacific Atlantic Water Flow

medium
TC: O(M * N) · SC: O(M * N)

Reverse flow from the coastlines uphill (`nextHeight >= currHeight`) instead of running downhill DFS from every cell. Intersect the Pacific-reachable set (`pac`) with the Atlantic-reachable set (`atl`).

Rotting Oranges

medium
TC: O(M * N) · SC: O(M * N)

Seed one **multi-source BFS** queue simultaneously with ALL initially rotten cells (`2`) while counting `fresh` cells (`1`). Process level-by-level while `q and fresh > 0`, decrementing `fresh` on each rot.

Word Ladder

hard
TC: O(N * L^2) · SC: O(N * L)

Avoid O(N^2 * L) pairwise comparisons by indexing dictionary words onto wildcard patterns (`h*t -> ["hot", "hit"]`), or run **bidirectional BFS** generating 26 char substitutions per position on the smaller frontier.