2D Arrays & Matrices

RoadmapsDSA

Overview

A 2D array (or matrix) is an array of arrays. It organizes data into rows and columns, accessed via two indices, typically `matrix[row][col]`. Under the hood, memory is fundamentally 1-dimensional, so the computer flattens the grid into a single contiguous line.

Many real-world problems are inherently two-dimensional: maps, spreadsheets, images, and mathematical matrices. 2D arrays provide a natural mental model to represent and traverse these spatial structures.

Where used: Dynamic Programming: building a 2D table to cache subproblem results, Graph representations: Adjacency matrices represent connections between nodes

Why learn this

Aha moment

# Python pitfall:
bad_grid = [[0] * 3] * 3
bad_grid[0][0] = 9
print(bad_grid) 
# Output: [[9, 0, 0], [9, 0, 0], [9, 0, 0]]

# Correct way:
good_grid = [[0 for _ in range(3)] for _ in range(3)]
good_grid[0][0] = 9
print(good_grid)
# Output: [[9, 0, 0], [0, 0, 0], [0, 0, 0]]

Prediction: Modifying `bad_grid[0][0]` will only change the top-left corner.

Common guess: Both grids behave exactly the same way.

The `* 3` operator duplicates REFERENCES to the same inner list. You don't have a 3x3 grid; you have one row with 3 pointers pointing to it. The list comprehension creates 3 distinct, independent lists in memory.

Common mistakes

Glossary

contiguous line
A continuous, unbroken sequence of memory.
cache-efficient
Written in a way that helps the computer memory.
Cartesian math
A coordinate system.

Recall questions

Understanding checks

A matrix has 5 rows and 4 columns. To flatten it to a 1D array using row-major order, the formula for a 1D index is `(row * NUMBER_OF_COLUMNS) + col`. Why do we multiply by the number of columns instead of the number of rows?

Because to get to row 3, you have to skip entirely over row 0, row 1, and row 2. Each of those rows contains exactly `NUMBER_OF_COLUMNS` elements.

This is the fundamental math the compiler uses to translate a 2D access into a 1D memory address. Understanding it demystifies how multi-dimensional data is actually stored.

You write a function to search a grid. It checks `grid[r+1][c]` to look down. However, when you are on the very bottom row, the program crashes with an 'Index Out of Bounds' error. How do you fix this structurally?

You must check boundaries before accessing the index: `if r + 1 < len(grid): check(grid[r+1][c])`. Guarding directional moves is mandatory in grid traversal.

Boundary checking is the single most common source of bugs in matrix problems. You must always ensure the next coordinate is within `0 <= r < ROWS` and `0 <= c < COLS`.

Practice tasks

Define directional vectors

When traversing a matrix (like in a maze), it's messy to write 4 separate if-statements for Up, Down, Left, Right. Define an array of coordinate pairs `directions` that you can loop over to safely get the 4 adjacent neighbors of `(r, c)`.

Continue learning

Previous: Arrays & Memory

Return to DSA Roadmap