Rotating a matrix by 90 degrees is a fundamental operation in computer science, frequently appearing in coding interviews, competitive programming, and real-world applications like image processing and computer graphics. At its core, this transformation repositions the elements of a two-dimensional array so that the first row becomes the last column, the second row becomes the second-to-last column, and so on. Mastering this concept requires understanding both the mathematical geometry behind the rotation and the algorithmic techniques to implement it efficiently, specifically focusing on the distinction between creating a new matrix and performing an in-place rotation It's one of those things that adds up..
Quick note before moving on It's one of those things that adds up..
Understanding the Geometry of Rotation
Before diving into code, it helps to visualize what happens to the coordinates of an element during a 90-degree clockwise rotation. Consider a matrix with dimensions $N \times N$ (square matrix). An element located at index (row, col) moves to a new position (col, N - 1 - row) Surprisingly effective..
Imagine a 3x3 grid:
[ (0,0) (0,1) (0,2) ]
[ (1,0) (1,1) (1,2) ]
[ (2,0) (2,1) (2,2) ]
After a 90-degree clockwise turn:
- Element at
(0,0)moves to(0, 2). That said, * Element at(2,2)moves to(2, 0). * Element at(0,2)moves to(2, 2). - Element at
(2,0)moves to(0, 0).
These four corners form a cycle. Practically speaking, every rotation operation essentially involves moving elements along these cycles. For an $N \times N$ matrix, there are $\lfloor N/2 \rfloor$ concentric "layers" or "rings," and within each layer, elements swap positions in groups of four. This geometric insight is the key to the optimal in-place algorithm.
Approach 1: The Brute Force Method (Auxiliary Matrix)
The most intuitive way to rotate a matrix is to create a new matrix of the same dimensions and map the old indices to the new ones directly. This approach is straightforward to implement and understand, making it a great starting point for beginners And that's really what it comes down to..
Algorithm Steps:
- Initialize a new $N \times N$ matrix, let's call it
rotated. - Iterate through every cell
(i, j)of the original matrix. - Assign
rotated[j][N - 1 - i] = matrix[i][j]. - Return the
rotatedmatrix.
Complexity Analysis:
- Time Complexity: $O(N^2)$ — We must visit every element exactly once.
- Space Complexity: $O(N^2)$ — We allocate a completely new matrix to store the result.
Python Implementation:
def rotate_brute_force(matrix):
n = len(matrix)
# Initialize a new n x n matrix filled with zeros
rotated = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
# Map (i, j) -> (j, n - 1 - i)
rotated[j][n - 1 - i] = matrix[i][j]
return rotated
While this method is clean, the $O(N^2)$ space complexity is often unacceptable in memory-constrained environments or strict interview settings where in-place modification is a hard requirement The details matter here..
Approach 2: The Optimal In-Place Rotation (Layer by Layer)
To achieve $O(1)$ auxiliary space, we must swap elements within the original matrix without allocating a second 2D array. The standard technique processes the matrix layer by layer, starting from the outermost ring and moving inward.
The "Four-Way Swap" Logic
For a single layer, we iterate through the elements of the top row (excluding the last corner element, which is handled by the first iteration). For each element at offset i on the top row, we identify its three counterparts on the right column, bottom row, and left column. We then perform a 4-way swap using a single temporary variable.
Indices for a layer layer and offset i:
- Top:
(layer, layer + i) - Right:
(layer + i, n - 1 - layer) - Bottom:
(n - 1 - layer, n - 1 - layer - i) - Left:
(n - 1 - layer - i, layer)
Algorithm Steps:
- Determine the number of layers:
layers = n // 2. - Loop
layerfrom0tolayers - 1. - Define
first = layerandlast = n - 1 - layer. - Loop
ifromfirsttolast - 1. - Calculate
offset = i - first. - Save
topelement intemp. - Move
left->top. - Move
bottom->left. - Move
right->bottom. - Move
temp(savedtop) ->right.
Complexity Analysis:
- Time Complexity: $O(N^2)$ — Still touches every element once.
- Space Complexity: $O(1)$ — Only uses a single temporary variable for swapping.
Python Implementation:
def rotate_in_place(matrix):
n = len(matrix)
# Iterate through layers (onion peeling)
for layer in range(n // 2):
first = layer
last = n - 1 - layer
for i in range(first, last):
offset = i - first
# Save top
top = matrix[first][i]
# Left -> Top
matrix[first][i] = matrix[last - offset][first]
# Bottom -> Left
matrix[last - offset][first] = matrix[last][last - offset]
# Right -> Bottom
matrix[last][last - offset] = matrix[i][last]
# Top (saved) -> Right
matrix[i][last] = top
Approach 3: The "Transpose and Reverse" Technique
There is a second in-place method that is often easier to remember and implement correctly under pressure. It relies on two distinct linear algebra operations: Transpose followed by Horizontal Reflection (Reverse Rows).
Mathematical Proof
A 90-degree clockwise rotation matrix $R$ can be decomposed as: $R = H \times T$ Where $T$ is the Transpose operation ($A^T_{ij} = A_{ji}$) and $H$ is the Horizontal Flip ($H_{ij} = A_{i, N-1-j}$) Practical, not theoretical..
Let's trace an element (i, j):
- Transpose:
(i, j)$\rightarrow$(j, i) - Reverse Row:
(j, i)$\rightarrow$(j, N - 1 - i)This matches the target coordinate for a 90-degree rotation perfectly.
Algorithm Steps:
- Transpose the matrix: Swap
matrix[i][j]withmatrix[j][i]for all $i < j$. (Only iterate upper triangle to avoid double-swapping). - Reverse each row: For every row
i, reverse the arraymatrix[i].
Complexity Analysis:
- Time Complexity: $O(N^2)$ — Transpose takes ~$N^2/2$ swaps; Reverse takes $N^2/2$ swaps.
- Space Complexity: