Home
DSA Patterns
Depth-First Search
Matrices as Graphs
Matrices as Graphs
Treating 2D Grids as implicit graphs.
2D Grid as a Graph
Many problems involve a 2D Matrix (Grid). This is implicitly a Graph.
- Node: Each cell
(r, c)is a node. - Edges: Adjacent cells (Up, Down, Left, Right) are neighbors.
So a matrix of size M x N is a graph with M*N nodes.
Interactive Visualization
Run the directions-array DFS on a grid of open cells (1) and walls (0). Each step tries one direction from the running cell: the arrow shows the move, and a move off the edge lands on an empty cell outside the grid before it is skipped. The calls still waiting form the live path back to the start.
Code: DFS with a Directions Array
Instead of writing 4 if statements, use a directions array to iterate neighbors cleanly.
The function below puts it to work: it counts the open cells (1) reachable from (sr, sc). It marks each cell in a visited grid, tries the four directions in order — right, down, left, up — and skips any neighbour that is out of bounds, a wall (0), or already visited.
Matrices as Graphs Code
1var countReachable = function(grid, sr, sc) {2 const rows = grid.length, cols = grid[0].length;3 const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]; // right, down, left, up4 const visited = Array.from({ length: rows }, () => new Array(cols).fill(false));56 function dfs(r, c) {7 visited[r][c] = true;8 let count = 1;9 for (const [dr, dc] of directions) {10 const nr = r + dr, nc = c + dc;11 if (nr < 0 || nr >= rows || nc < 0 || nc >= cols) {12 continue;13 }14 if (grid[nr][nc] === 0 || visited[nr][nc]) {15 continue;16 }17 count += dfs(nr, nc);18 }19 return count;20 }2122 if (grid[sr][sc] === 0) {23 return 0;24 }25 return dfs(sr, sc);26};
DFS on a Grid (Flood Fill)
DFS on a grid is often called Flood Fill.
Since we can move in 4 directions, cycles are everywhere (A -> B -> C -> D -> A). We MUST handle visited cells.
Space Optimization: Instead of a separate visited set, we can often modify the input grid itself (e.g., change '1' to '0' or '#') to mark it as visited, saving O(M*N) space.
Boundary Checks
Always check if the new coordinates are valid before accessing the matrix.
if (r < 0 || c < 0 || r >= rows || c >= cols) -> Invalid.
Dry Run (DFS Traversal)
Grid: [[1,1,0],[0,1,1],[1,0,1]], start (0,0). Each row is one dfs call; its four directions are tried left to right, and a → call runs to completion before the next direction is tried.
| Call | Right | Down | Left | Up | Returns |
|---|---|---|---|---|---|
dfs(0,0) |
(0,1) open → call | (1,0) wall | outside | outside | 1 + 4 = 5 |
dfs(0,1) |
(0,2) wall | (1,1) open → call | (0,0) visited | outside | 1 + 3 = 4 |
dfs(1,1) |
(1,2) open → call | (2,1) wall | (1,0) wall | (0,1) visited | 1 + 2 = 3 |
dfs(1,2) |
outside | (2,2) open → call | (1,1) visited | (0,2) wall | 1 + 1 = 2 |
dfs(2,2) |
outside | outside | (2,1) wall | (1,2) visited | 1 |
The answer is 5. Cell (2,0) is open but no path of open cells reaches it, so it is never visited.
Edge Cases & Common Mistakes
Crucial checks for Grid problems:
Out of Bounds: Accessing
grid[r][c]whenr < 0orr >= rowscrashes the code.Infinite Loops: Forgetting to mark cells as
visitedleads to stack overflow in cycles.Empty Grid: If the grid can be empty, check
gridandgrid[0]before reading the column count.Non-Rectangular Grids: Rare (Jagged Arrays), but standard problems assume Rectangular (MxN).
Summary
- Matrix problems = Graph problems.
- Use a
directionsarray, such as[[0,1],[1,0],[0,-1],[-1,0]](right, down, left, up). - Always check bounds
(r >= 0 && r < M). - Use a Visited set or modify the grid to avoid cycles.
