Transpose Matrix
Flip a grid over its diagonal — the index swap that underlies rotation, and the loop bound that makes it work
Problem Statement
Return the transpose of a matrix: rows become columns and columns become rows.
Input: [[1,2,3],
[4,5,6],
[7,8,9]]
Output: [[1,4,7],
[2,5,8],
[3,6,9]]
Input: [[1,2,3],
[4,5,6]] 2 rows, 3 columns
Output: [[1,4],
[2,5],
[3,6]] 3 rows, 2 columnsIntuition
The rule is one line: result[c][r] = grid[r][c]. Swap the two indices.
Visually, it is a reflection across the main diagonal — the line from top-left to bottom-right. Values on that diagonal do not move, because swapping r and c when they are equal changes nothing.
1 2 3 1 . .
4 5 6 → . 5 . the diagonal stays put
7 8 9 . . 9The shape changes too
An m × n matrix transposes into an n × m one. For a 2×3 input the output has 3 rows and 2 columns.
This is why the general solution builds a new grid: you cannot reshape a rectangle in place. Only a square matrix can be transposed in place, which is the case Rotate Image relies on.
Approach
Measure both dimensions
rows = len(grid), cols = len(grid[0]). Do this first — the output uses them the other way round.
Build a cols × rows grid
Note the reversal. Using rows × cols fails on any non-square input.
Copy every cell to its swapped position
result[c][r] = grid[r][c].
Solution
def transpose(matrix: list[list[int]]) -> list[list[int]]:
"""Return the transpose: result[c][r] = matrix[r][c]."""
rows, cols = len(matrix), len(matrix[0])
result = [[0] * rows for _ in range(cols)]
for r in range(rows):
for c in range(cols):
result[c][r] = matrix[r][c]
return resultThe output is built with [[0] * rows for _ in range(cols)] — cols rows of length rows. Getting these the wrong way round is the main trap.
A one-liner exists: [list(row) for row in zip(*matrix)]. It is idiomatic and correct; the explicit loop is what shows the index swap.
The in-place version, and why `c` starts at `r`
For a square matrix you can swap pairs directly with no new grid:
for r in range(n):
for c in range(r, n): ← starts at r, not 0
grid[r][c], grid[c][r] = grid[c][r], grid[r][c]Starting c at 0 swaps every pair twice — once as (r,c) and again as (c,r) — returning the matrix exactly as it began.
That bug produces no error and no visible symptom except the output being the input. Starting at r visits each pair once and skips the diagonal, which never needs moving.
Complexity Analysis
Time Complexity
O(rows × cols)
Space Complexity
O(rows × cols)
Time — every cell is copied once. There is no way to do better; the output has that many cells.
Space — the new grid. The in-place square version is O(1), but it cannot handle rectangles.
Edge Cases
Related Problems
- Rotate Image — transpose plus a row reversal gives a 90° rotation
- Spiral Matrix — a different way of walking the same grid
- Matrix — the index conventions and the reference trap