Browse curriculum

Matrices as Graphs

Treating 2D Grids as implicit graphs.

Medium
10 min

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, up
4 const visited = Array.from({ length: rows }, () => new Array(cols).fill(false));
5
6 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 }
21
22 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] when r < 0 or r >= rows crashes the code.

  • Infinite Loops: Forgetting to mark cells as visited leads to stack overflow in cycles.

  • Empty Grid: If the grid can be empty, check grid and grid[0] before reading the column count.

  • Non-Rectangular Grids: Rare (Jagged Arrays), but standard problems assume Rectangular (MxN).

Summary

  1. Matrix problems = Graph problems.
  2. Use a directions array, such as [[0,1],[1,0],[0,-1],[-1,0]] (right, down, left, up).
  3. Always check bounds (r >= 0 && r < M).
  4. Use a Visited set or modify the grid to avoid cycles.

The approach, step by step

  1. Mark the cell

    Set visited[r][c] and start the count at 1.

  2. Try each direction

    For each (dr, dc), skip the neighbour if it is out of bounds, a wall, or already visited.

  3. Recurse and return

    Add dfs(neighbour) to the count for every other neighbour, then return the count.

Frequently asked questions

Why treat a matrix as a graph?

Each cell is a node and its up, down, left and right neighbours are its edges. Once you see that, grid problems like islands, flood fill and mazes become ordinary graph searches.


Why use a directions array?

It replaces four near-identical blocks of code with one loop. The bounds check and the visited check are written once, so they cannot drift apart between directions.


Do I need a separate visited grid?

You need some way to mark cells, or DFS will walk in circles. A visited grid leaves the input untouched; when changing the input is allowed, overwriting a cell (for example with 0) saves that extra memory.

Applying for software engineering roles? Free, no sign-up:

AI resume checker — match your resume to the job description