Skip to content
← All posts

Transpose Matrix: Row-Column Swap Pattern

7 min read
leetcodeproblemeasyarraysmatrix

You are given a 2D integer matrix. Return its transpose. The transpose of a matrix swaps its row and column indices: the element at position [i][j] in the original ends up at position [j][i] in the result. That is LeetCode 867: Transpose Matrix, and it is one of the cleanest introductions to matrix index manipulation you will find.

Original (2x3)1c02c13c2456TransposeTransposed (3x2)1c04c12536
Transposing swaps rows and columns. Row 0 of the original [1, 2, 3] becomes column 0 of the result. Row 1 [4, 5, 6] becomes column 1.

Why this problem matters

Transpose is a fundamental operation in linear algebra, image processing, and data manipulation. In interviews, it shows up both as a standalone problem and as a building block inside harder problems. For example, rotating a matrix 90 degrees clockwise is just "transpose, then reverse each row." If you cannot write the transpose step cleanly, the rotation problem becomes twice as hard.

This problem also forces you to think carefully about dimensions. The input might be m x n where m is not equal to n, so the output matrix has different dimensions than the input. That rules out in-place solutions and makes you reason about row-column swaps explicitly.

The brute force approach

Since the transpose changes dimensions (an m x n matrix becomes n x m), you cannot do this in place. You need a new matrix. The simplest approach is to create the result matrix up front and copy each element to its transposed position.

def transpose(matrix):
    m, n = len(matrix), len(matrix[0])
    result = [[0] * m for _ in range(n)]
    for i in range(m):
        for j in range(n):
            result[j][i] = matrix[i][j]
    return result

This is already optimal. There is no clever trick that avoids visiting every element, because every element needs to appear in the output. The "brute force" and the "optimal" solution are the same thing here. The challenge is writing it correctly and understanding why the index swap works.

The key insight: rows become columns

The entire operation boils down to one rule: result[j][i] = matrix[i][j]. Every row in the original becomes a column in the result, and every column becomes a row. The first row [1, 2, 3] becomes the first column [1, 2, 3] (reading top to bottom). The second row [4, 5, 6] becomes the second column.

This also means the result has n rows and m columns, which is the reverse of the original dimensions. If you forget to swap the dimensions when creating the result matrix, you will get an index error or a wrong-shaped output.

A quick way to remember: the number of rows in the transpose equals the number of columns in the original, and vice versa. If the input is 2x3, the output is 3x2.

Walking through it step by step

Let's trace through matrix = [[1, 2, 3], [4, 5, 6]] and see exactly where each element lands.

Step 1: Original matrix (2x3)

Row 0123Row 1456

We start with a 2x3 matrix. The transpose will be a 3x2 matrix. Create a new result matrix with dimensions rows=3, cols=2.

Step 2: Map row 0 to column 0 of the result

Result row 01?Result row 12?Result row 23?

original[0][0]=1 goes to result[0][0]. original[0][1]=2 goes to result[1][0]. original[0][2]=3 goes to result[2][0]. Each element at [r][c] maps to [c][r].

Step 3: Map row 1 to column 1 of the result

Result row 014Result row 125Result row 236

original[1][0]=4 goes to result[0][1]. original[1][1]=5 goes to result[1][1]. original[1][2]=6 goes to result[2][1]. Column 1 is now filled.

Step 4: Final transposed matrix (3x2)

Row 014Row 125Row 236

The transpose is complete. Every element that was at position [r][c] in the original is now at [c][r] in the result. Rows became columns, columns became rows.

Each element at [i][j] moves to [j][i]. That is the only rule. No swaps, no temporary variables, just a direct copy into the new position.

The clean solution

Python gives you a one-liner using zip, which naturally groups elements by column index:

def transpose(matrix):
    return [list(row) for row in zip(*matrix)]

The *matrix unpacks each row as a separate argument to zip. Then zip groups the first element of each row together, the second elements together, and so on. Each group becomes a row in the transposed matrix. The list() call converts each tuple from zip into a list.

If you prefer the explicit loop version for clarity:

def transpose(matrix):
    m, n = len(matrix), len(matrix[0])
    result = [[0] * m for _ in range(n)]
    for i in range(m):
        for j in range(n):
            result[j][i] = matrix[i][j]
    return result

Both produce the same result. The explicit version makes the [j][i] = [i][j] swap visible, which is better for interviews where you want to show your understanding.

The zip(*matrix) trick is Python-specific. In an interview, mention it to show language fluency, but be ready to write the explicit loop version if asked. Interviewers want to see that you understand the index mapping, not just that you know a shortcut.

Complexity analysis

MetricValue
TimeO(m * n), every element is visited exactly once
SpaceO(m * n), the result matrix holds all elements in transposed positions

Time: The nested loop visits each of the m * n elements once and performs a constant-time copy. No element is visited more than once.

Space: The output matrix is n x m, which holds the same number of elements as the input. This is required output space, not extra auxiliary space. The only additional variables are loop counters and dimension values, which is O(1).

Building blocks

This problem teaches two reusable patterns that CodeBricks drills independently.

1. Index-swap matrix construction

The pattern of creating a new matrix with swapped dimensions and mapping elements via index reversal:

result = [[0] * m for _ in range(n)]
for i in range(m):
    for j in range(n):
        result[j][i] = matrix[i][j]

This same index-swap logic is the first half of the Rotate Image solution (LeetCode 48). It also appears in problems that ask you to reflect a matrix across its diagonal. Once you can write the transpose from memory, any problem that says "swap rows and columns" or "reflect across the diagonal" becomes a one-step operation.

2. Dimension-aware matrix creation

The pattern of computing output dimensions from input dimensions before building the result:

m, n = len(matrix), len(matrix[0])
result = [[0] * m for _ in range(n)]

Getting this wrong is the most common source of bugs in matrix transformation problems. The result has n rows (one per original column) and m columns (one per original row). This dimension reasoning applies to any problem where the output matrix has a different shape than the input, including matrix multiplication and convolution operations.

Edge cases

  • Square matrix: A 3x3 matrix transposes to another 3x3 matrix. The diagonal elements stay in place, and off-diagonal elements swap. This is the only case where an in-place transpose is possible.
  • Single row: [[1, 2, 3]] (1x3) transposes to [[1], [2], [3]] (3x1). Each element becomes its own row.
  • Single column: [[1], [2], [3]] (3x1) transposes to [[1, 2, 3]] (1x3). The reverse of the single-row case.
  • Single element: [[5]] (1x1) transposes to [[5]]. The trivial case, but worth verifying your dimension logic handles it.
  • Rectangular matrix with m > n: A 4x2 matrix becomes 2x4. Make sure your loop bounds use the original dimensions, not the transposed ones.

Common mistakes

1. Creating the result matrix with wrong dimensions. Writing [[0] * n for _ in range(m)] instead of [[0] * m for _ in range(n)] gives you the same shape as the input, which is wrong for non-square matrices. The rows and columns must be swapped.

2. Confusing which index goes where. Writing result[i][j] = matrix[j][i] instead of result[j][i] = matrix[i][j] produces the same result when iterating over the original matrix dimensions, but it is easy to mix up if you change which matrix you are iterating over. Always iterate over the original and assign to the transposed position.

3. Trying to transpose in place for non-square matrices. In-place transpose only works when m == n. For rectangular matrices, the dimensions change, so you must allocate a new matrix. Attempting in-place modification will either crash or corrupt the data.

4. Forgetting that zip returns tuples. If you use the zip(*matrix) approach and forget to wrap each result in list(), you return a list of tuples instead of a list of lists. Some LeetCode judges accept tuples, but others do not.

From understanding to recall

You now understand the index swap rule: result[j][i] = matrix[i][j]. It is one line of logic. But under interview pressure, even simple things slip. Do you create the result as n x m or m x n? Do you assign result[j][i] or result[i][j]? Is the outer loop over m or n?

Spaced repetition locks these details in. You write the dimension calculation, the matrix initialization, and the nested loop from scratch. You do it today, again in two days, again in five. After a few reps, you see "transpose" in a problem statement and the three-line solution appears on your screen without hesitation. No second-guessing the index order, no confusion about dimensions.

The transpose pattern is one of roughly 60 reusable building blocks that cover hundreds of LeetCode problems. Learning these individually and drilling them with spaced repetition is far more effective than grinding random problems and hoping the patterns stick.

Related posts

  • Rotate Image - Uses transpose as the first step of a 90-degree rotation, then reverses each row
  • Spiral Matrix - Another matrix traversal pattern where index management is the core challenge
  • Set Matrix Zeroes - In-place matrix modification that requires careful row and column tracking

CodeBricks breaks Transpose Matrix into its index-swap and dimension-aware construction building blocks, then drills them independently with spaced repetition. You type the result[j][i] = matrix[i][j] loop from scratch until the pattern is automatic. When a matrix transformation problem shows up in your interview, you do not think about it. You just write it.