title: Transpose Matrix
slug: transpose-matrix
difficulty: easy
leetcode_id: 867
leetcode_url: https://leetcode.com/problems/transpose-matrix/
categories:
  - arrays
patterns:
  - slug: matrix-traversal
    is_optimal: true

function_signature: "def transpose(matrix: list[list[int]]) -> list[list[int]]:"

test_cases:
  visible:
    - input: { matrix: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] }
      expected: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
    - input: { matrix: [[1, 2, 3], [4, 5, 6]] }
      expected: [[1, 4], [2, 5], [3, 6]]
  hidden:
    - input: { matrix: [[1]] }
      expected: [[1]]
    - input: { matrix: [[1, 2], [3, 4]] }
      expected: [[1, 3], [2, 4]]
    - input: { matrix: [[1], [2], [3]] }
      expected: [[1, 2, 3]]
    - input: { matrix: [[1, 2, 3, 4]] }
      expected: [[1], [2], [3], [4]]

description: |
  Given a 2D integer array `matrix`, return *the **transpose** of* `matrix`.

  The **transpose** of a matrix is the matrix flipped over its main diagonal, switching the matrix's row and column indices.

  In other words, for every element at position `matrix[i][j]`, its transposed position becomes `result[j][i]`.

constraints: |
  - `m == matrix.length`
  - `n == matrix[i].length`
  - `1 <= m, n <= 1000`
  - `1 <= m * n <= 10^5`
  - `-10^9 <= matrix[i][j] <= 10^9`

examples:
  - input: "matrix = [[1,2,3],[4,5,6],[7,8,9]]"
    output: "[[1,4,7],[2,5,8],[3,6,9]]"
    explanation: "The 3x3 matrix is flipped along its main diagonal. Row 0 becomes column 0, row 1 becomes column 1, etc."
  - input: "matrix = [[1,2,3],[4,5,6]]"
    output: "[[1,4],[2,5],[3,6]]"
    explanation: "The 2x3 matrix becomes a 3x2 matrix. Each row of the original becomes a column in the result."

explanation:
  intuition: |
    Imagine physically rotating a matrix 90 degrees clockwise, then flipping it horizontally — that's essentially what transposing does, but there's an easier way to think about it.

    Picture each element in the matrix as having a "home address" of `(row, column)`. When you transpose, every element simply **swaps its row and column indices**. The element at `(0, 2)` moves to `(2, 0)`. The element at `(1, 0)` moves to `(0, 1)`.

    Think of it like this: if you were reading the original matrix row by row from left to right, the transposed matrix reads the original *column by column* from top to bottom.

    The key insight is that a matrix with dimensions `m × n` becomes `n × m` after transposition. This means we need to create a **new matrix** with swapped dimensions — we can't just rearrange elements in place (unless the matrix is square).

  approach: |
    We solve this using a **Direct Mapping Approach**:

    **Step 1: Determine the dimensions**

    - Get `m` (number of rows) and `n` (number of columns) from the original matrix
    - The result will have dimensions `n × m` (rows and columns swapped)

    &nbsp;

    **Step 2: Create the result matrix**

    - Initialise a new matrix with `n` rows and `m` columns
    - This can be done by creating `n` empty lists, each eventually containing `m` elements

    &nbsp;

    **Step 3: Copy elements with swapped indices**

    - Iterate through each element in the original matrix at position `(i, j)`
    - Place it in the result matrix at position `(j, i)`
    - This naturally swaps rows and columns

    &nbsp;

    **Step 4: Return the transposed matrix**

    - After processing all elements, return the result matrix

    &nbsp;

    This approach works because the mathematical definition of transpose is exactly this index swap: `result[j][i] = matrix[i][j]` for all valid `i` and `j`.

  common_pitfalls:
    - title: Confusing Transpose with Rotation
      description: |
        A common mistake is thinking transpose means rotating 90 degrees. They're related but different:

        - **Transpose**: Swap row and column indices — `(i,j)` → `(j,i)`
        - **Rotate 90° clockwise**: More complex — `(i,j)` → `(j, m-1-i)`

        For a 3x3 matrix `[[1,2,3],[4,5,6],[7,8,9]]`:
        - Transpose gives `[[1,4,7],[2,5,8],[3,6,9]]`
        - 90° rotation gives `[[7,4,1],[8,5,2],[9,6,3]]`
      wrong_approach: "Applying rotation logic instead of index swap"
      correct_approach: "Simply swap indices: result[j][i] = matrix[i][j]"

    - title: In-Place Modification for Non-Square Matrices
      description: |
        With a square matrix (`n × n`), you might be tempted to swap elements in place. But for a non-square matrix (`m × n` where `m ≠ n`), the dimensions change!

        A `2 × 3` matrix becomes `3 × 2`. You cannot do this in place because the result has a different shape than the input. Always create a new matrix with the transposed dimensions.
      wrong_approach: "Trying to swap elements in place for m × n matrix"
      correct_approach: "Create a new n × m matrix and map elements"

    - title: Wrong Dimension Order
      description: |
        When creating the result matrix, remember the dimensions flip. If the original is `m` rows by `n` columns, the result is `n` rows by `m` columns.

        Getting this wrong leads to index out of bounds errors or incorrectly shaped output.
      wrong_approach: "Creating result with same dimensions as input"
      correct_approach: "Result dimensions are (n, m) when input is (m, n)"

  key_takeaways:
    - "**Index swapping pattern**: Transposition is simply `result[j][i] = matrix[i][j]` — a fundamental matrix operation"
    - "**Dimension awareness**: Always consider how matrix operations change dimensions — transpose swaps `m × n` to `n × m`"
    - "**Foundation for linear algebra**: Transpose is essential for operations like computing dot products, matrix multiplication, and solving linear systems"
    - "**Applicable to many problems**: Understanding matrix traversal patterns helps with rotation, spiral order, and diagonal traversal problems"

  time_complexity: "O(m × n). We visit each element in the matrix exactly once to copy it to the new position."
  space_complexity: "O(m × n). We create a new matrix to store the transposed result, which has the same total number of elements."

solutions:
  - approach_name: Direct Mapping
    is_optimal: true
    code: |
      def transpose(matrix: list[list[int]]) -> list[list[int]]:
          # Get original dimensions
          m, n = len(matrix), len(matrix[0])

          # Create result matrix with swapped dimensions (n rows, m columns)
          # Each position result[j][i] will hold matrix[i][j]
          result = [[0] * m for _ in range(n)]

          # Copy each element with swapped indices
          for i in range(m):
              for j in range(n):
                  result[j][i] = matrix[i][j]

          return result
    explanation: |
      **Time Complexity:** O(m × n) — We iterate through every element once.

      **Space Complexity:** O(m × n) — We store all elements in a new matrix.

      This is optimal because we must at minimum read every element and write every element to produce the output, which requires O(m × n) operations.

  - approach_name: List Comprehension (Pythonic)
    is_optimal: true
    code: |
      def transpose(matrix: list[list[int]]) -> list[list[int]]:
          # zip(*matrix) unpacks rows and zips them column-wise
          # Each tuple from zip becomes a row in the transposed matrix
          return [list(row) for row in zip(*matrix)]
    explanation: |
      **Time Complexity:** O(m × n) — Same as direct mapping, just more concise.

      **Space Complexity:** O(m × n) — Creates a new matrix for the result.

      This Pythonic approach uses `zip(*matrix)` to unpack the matrix rows and re-group elements by column index. The `*` operator unpacks the rows, and `zip` collects elements at the same position from each row — exactly what transpose does. We convert each tuple to a list for the final result.

  - approach_name: Using NumPy
    is_optimal: true
    code: |
      import numpy as np

      def transpose(matrix: list[list[int]]) -> list[list[int]]:
          # NumPy provides a built-in transpose operation
          # .T is shorthand for np.transpose()
          return np.array(matrix).T.tolist()
    explanation: |
      **Time Complexity:** O(m × n) — NumPy optimises the operation internally.

      **Space Complexity:** O(m × n) — Creates the result array.

      While not typically allowed in coding interviews, this shows how common matrix transpose is — it's built into numerical computing libraries. NumPy's `.T` attribute returns a transposed view of the array, and `tolist()` converts it back to a Python list of lists.
