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)   **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   **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   **Step 4: Return the transposed matrix** - After processing all elements, return the result matrix   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.