Pattern 20 of 20

Matrix

Index arithmetic on grids: layer-by-layer traversal, in-place updates and prefix sums.

When to use it

  • Rotating, transposing or spiralling a 2-D array
  • Marking rows and columns without extra memory
  • Repeated rectangle sums over the same grid

The idea

Treat the grid as rows and columns of indices and get the boundaries right. In-place tricks reuse the first row or column as storage, and a 2-D prefix sum answers any rectangle in O(1).

Typical cost O(m·n) time, O(1) to O(m·n) extra space.

How it works

A matrix problem is an array problem with two coordinates. Most of the difficulty is bookkeeping: staying inside the bounds, visiting cells in the right order, and not overwriting a value you still need.

Keep a direction list such as [(0, 1), (1, 0), (0, -1), (-1, 0)] and loop over it instead of writing four near-identical blocks. Pair it with a single in-bounds check. Spiral traversals cycle through the same list, turning when they hit a boundary.

In-place transformations rely on decomposing the operation. A 90-degree clockwise rotation is a transpose followed by reversing each row. Setting rows and columns to zero in O(1) extra space uses the first row and first column as marker storage.

When cells are nodes and neighbors are edges, the matrix is a graph: flood fill, islands and shortest paths through a maze are graph traversals. Sorted matrices add a search angle: starting from the top-right corner, each comparison eliminates a row or a column.

How to attack it

  1. 1Write rows and cols once and a single in-bounds helper.
  2. 2Use a direction list instead of repeated neighbor code.
  3. 3Decide whether you need a copy or can transform in place, and in which order.
  4. 4Treat cells as graph nodes when the question is about connectivity or distance.
  5. 5Test with 1 × 1, a single row, a single column, and a non-square matrix.

Template

A skeleton to adapt, not a solution to paste. Write it from memory a few times.

DIRS = [(0, 1), (1, 0), (0, -1), (-1, 0)]   # right, down, left, up


def spiral(matrix):
    if not matrix:
        return []
    rows, cols = len(matrix), len(matrix[0])
    seen = [[False] * cols for _ in range(rows)]
    r = c = d = 0
    out = []
    for _ in range(rows * cols):
        out.append(matrix[r][c])
        seen[r][c] = True
        nr, nc = r + DIRS[d][0], c + DIRS[d][1]
        if not (0 <= nr < rows and 0 <= nc < cols) or seen[nr][nc]:
            d = (d + 1) % 4                      # turn clockwise
            nr, nc = r + DIRS[d][0], c + DIRS[d][1]
        r, c = nr, nc
    return out


def rotate_clockwise(m):
    # In place for a square matrix: transpose, then reverse each row.
    n = len(m)
    for i in range(n):
        for j in range(i + 1, n):
            m[i][j], m[j][i] = m[j][i], m[i][j]
    for row in m:
        row.reverse()

Variants

Spiral and diagonal traversal
Walk with a direction list and turn at boundaries, or shrink four boundaries (top, bottom, left, right) after each side.
In-place rotation
Transpose then reverse rows for clockwise; reverse rows then transpose for counterclockwise.
Marker storage
Use the first row and column (plus one flag) to remember which rows and columns to zero, for O(1) extra space.
Grid as a graph
Flood fill, islands and shortest paths: DFS or BFS over the four (or eight) neighbors.
Sorted matrix search
Start at the top-right corner and move left or down, or binary search a fully sorted matrix as one flat array.

Pitfalls

  • Swapping rows and columns in bounds checks on non-square input.
  • Transposing the whole matrix with j starting at 0, which swaps every pair twice and undoes itself.
  • Overwriting cells you still need to read when updating in place (use a copy or encode two states in one cell).
  • Building rows in Python with [[0] * cols] * rows, which aliases every row.
  • Forgetting the empty matrix or the empty first row.

What it costs

OperationCost
Visit every cellO(rows × cols)
In-place rotationO(n²) time, O(1) space
Staircase search in a sorted matrixO(rows + cols)
Binary search on a flattened sorted matrixO(log(rows × cols))

25 Matrix problems

Easiest first. Problems marked Free can be solved without Pro.

  1. 1Swap Rows for ColumnsFreeEasy
  2. 2Sum of Both DiagonalsFreeEasy
  3. 3Count Below-Zero CellsFreeEasy
  4. 4Repack the GridEasy
  5. 5Constant Down Every DiagonalEasy
  6. 6Fullest Row in a Sorted Bit GridEasy
  7. 7Turn the Grid by Quarter TurnsEasy
  8. 8Soften the ImageEasy
  9. 9Read the Grid in a SpiralMedium
  10. 10Quarter-Turn the PhotoMedium
  11. 11Blank Out Rows and ColumnsMedium
  12. 12Zigzag Diagonal ReadoutMedium
  13. 13Wind Numbers Into a SpiralMedium
  14. 14Next Generation of the ColonyMedium
  15. 15Rectangle Totals on DemandMedium
  16. 16Finished Sudoku of Any SizeMedium
  17. 17Sort Every DiagonalMedium
  18. 18Neighbourhood TotalsMedium
  19. 19Largest Square Within BudgetMedium
  20. 20Rotate Every RingMedium
  21. 21Richest Block Under a CapHard
  22. 22Fewest Presses to Darken the PanelHard
  23. 23Longest Uphill TrailHard
  24. 24Count All-Lit RectanglesHard
  25. 25Tightest Frame Around the Ink BlotHard

Solve them in the browser, in Python or JavaScript.