Reading

Matrix Boundaries and Transformations

Turn grid traversal into explicit shrinking boundaries and verify in-place transformations geometrically.

65 min 4 objectives
Learning objectives
  • Represent an unvisited matrix region with four boundaries
  • Avoid duplicate traversal when boundaries cross mid-layer
  • Rotate a square matrix by transpose and row reversal
  • Select edge cases that expose matrix-index bugs

A matrix is an array plus geometry

Matrix problems feel harder because two indices move at once. The cure is to name the geometry: which rectangle is still unprocessed, which edge is being consumed, and when that rectangle becomes empty.

Spiral traversal as a shrinking rectangle

Spiral Matrix (LeetCode #54) gives an m × n matrix and asks for its values in spiral order: top row left-to-right, right side downward, bottom row right-to-left, left side upward, then repeat inward.

Track inclusive boundaries:

Code
top = 0                 bottom = rows - 1
left = 0                right = columns - 1

After consuming an edge, immediately move its boundary inward:

Code
function spiralOrder(matrix: number[][]): number[] {
  if (matrix.length === 0 || matrix[0].length === 0) return []

  const result: number[] = []
  let top = 0
  let bottom = matrix.length - 1
  let left = 0
  let right = matrix[0].length - 1

  while (top <= bottom && left <= right) {
    for (let column = left; column <= right; column += 1) {
      result.push(matrix[top][column])
    }
    top += 1

    for (let row = top; row <= bottom; row += 1) {
      result.push(matrix[row][right])
    }
    right -= 1

    if (top <= bottom) {
      for (let column = right; column >= left; column -= 1) {
        result.push(matrix[bottom][column])
      }
      bottom -= 1
    }

    if (left <= right) {
      for (let row = bottom; row >= top; row -= 1) {
        result.push(matrix[row][left])
      }
      left += 1
    }
  }
  return result
}

The two mid-loop checks are essential. In a single-row matrix, the top walk consumes everything and moves top beyond bottom. Walking the bottom edge afterward would emit the same row again. In a single-column matrix, the left-edge check prevents the same kind of duplication.

Rotation as two understandable transformations

Rotate Image (LeetCode #48) asks you to rotate an n × n matrix 90 degrees clockwise in place. Direct four-cell cycles work, but they are easy to index incorrectly. Compose two simpler operations:

  1. Transpose across the main diagonal: swap (row, column) with (column, row).
  2. Reverse every row.
Code
function rotateImage(matrix: number[][]): void {
  const size = matrix.length

  for (let row = 0; row < size; row += 1) {
    for (let column = row + 1; column < size; column += 1) {
      ;[matrix[row][column], matrix[column][row]] =
        [matrix[column][row], matrix[row][column]]
    }
  }

  for (const row of matrix) row.reverse()
}

Why start the inner loop at row + 1? Values on the diagonal map to themselves. Every off-diagonal pair should be swapped exactly once. Iterating over the entire square would swap each pair twice and undo the transpose.

Complexity and storage

Spiral traversal visits every cell once: O(rows · columns) time. Its result is required output; apart from that, four boundaries use O(1) auxiliary space. Rotation touches O(n²) cells and uses O(1) auxiliary space because each swap happens inside the matrix.

The matrix test set

Do not trust only a square 3×3 example. Trace these shapes:

  • empty matrix, if the contract allows it;
  • one cell;
  • one row;
  • one column;
  • 2×2;
  • more rows than columns;
  • more columns than rows.

For rotation, the problem requires a square matrix. Say that constraint rather than silently applying the algorithm to a rectangle.

Common mistakes

  • Mixing inclusive and exclusive boundaries.
  • Shrinking a boundary before its edge is consumed.
  • Omitting mid-layer checks and duplicating a row or column.
  • Transposing every (row, column) pair and swapping twice.
  • Using row count as column count for a rectangular matrix.
Checkpoint

Draw the unvisited region

After one spiral layer, write the four new boundaries and point to the remaining rectangle. Then map each corner of a 3×3 matrix through transpose-plus-reverse.