Rotate Image | Leetcode 48
Welcome to our guide on Rotate Image (Leetcode 48). This is a quintessential 2D Matrix manipulation problem. It tests your ability to translate a geometric, visual transformation into an array-index algorithm—with the incredibly strict constraint of absolutely NO extra memory allowed.
Problem Statement
You are given an n x n 2D matrix representing an image, rotate the image by 90 degrees (clockwise).
You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.
Example:
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [[7,4,1],[8,5,2],[9,6,3]]
Approach 1: Linear Algebra (Transpose + Reverse)
If you've studied linear algebra, there is a beautiful mathematical property we can exploit to rotate an entire matrix by 90 degrees clockwise without having to manage complex 4-way rotating pointers.
The rotation can be split into two fundamental steps:
- Transpose the Matrix: Swap the elements across the main diagonal.
matrix[i][j]swaps withmatrix[j][i]. - Reverse each Row: Iterate through every horizontal row and physically reverse the array elements.
graph LR
A["Original<br>1 2 3<br>4 5 6<br>7 8 9"] -->|"1. Transpose"| B["<br>1 4 7<br>2 5 8<br>3 6 9"]
B -->|"2. Reverse Rows"| C["Rotated 90°<br>7 4 1<br>8 5 2<br>9 6 3"]
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
n = len(matrix)
# Step 1: Transpose Matrix
for i in range(n):
# Start j from i to avoid double-swapping back!
for j in range(i, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
# Step 2: Reverse Every Row
for i in range(n):
matrix[i].reverse()
Complexity Analysis
| Metric | Complexity | Explanation |
|---|---|---|
| Time | O(M) | Where M is the total number of cells in the matrix (or N^2). We visit each cell during the transpose and again during the reverse. |
| Space | O(1) | Pure integer swaps natively inside the original allocated 2D structural array. |
Approach 2: Rotating 4 Cells at a Time (Layer by Layer)
If you aren't comfortable leaning on linear algebra, we can manually implement the visual rotation logic. We rotate the matrix layer by layer (like an onion), working from the outermost boundary inwards.
For any specific cycle of 4 correlated corners, we save the top_left into a temporary variable, and then overwrite them circularly:
bottom_left→top_leftbottom_right→bottom_lefttop_right→bottom_right- Temporary
top_left→top_right
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
left, right = 0, len(matrix) - 1
while left < right:
for i in range(right - left):
top, bottom = left, right
# Save the top_left coordinate
top_left = matrix[top][left + i]
# Move bottom_left into top_left
matrix[top][left + i] = matrix[bottom - i][left]
# Move bottom_right into bottom_left
matrix[bottom - i][left] = matrix[bottom][right - i]
# Move top_right into bottom_right
matrix[bottom][right - i] = matrix[top + i][right]
# Move safe top_left variable into top_right
matrix[top + i][right] = top_left
right -= 1
left += 1
Complexity Analysis
| Metric | Complexity | Explanation |
|---|---|---|
| Time | O(M) | We literally touch and relocate every single cell (total M cells) exactly one physical time. |
| Space | O(1) | All rotations are perfectly cyclic, isolated to a single temporary floating integer (topLeft). |