Skip to content

Coding patternsBlind 75

Rotate Image

A clockwise turn is a transpose followed by reversing each row, and both steps swap cells in place. Solved two ways, copying into a new grid with O(n²) extra space and transpose then reverse with O(1) extra space, both O(n²) time, with a step-through, code in five languages and the Big O worked out from the code.

You are given an n × n grid of numbers, matrix. The code calls n size. Turn it 90 degrees clockwise. Change matrix itself: do not build and return a second grid.

Example 1

Input: matrix = [[10, 11, 12, 13], [14, 15, 16, 17], [18, 19, 20, 21], [22, 23, 24, 25]]

Output: [[22, 18, 14, 10], [23, 19, 15, 11], [24, 20, 16, 12], [25, 21, 17, 13]]

The top row, 10 to 13, is now the right column, read top to bottom.

c0c1c2c3
r022181410
r123191511
r224201612
r325211713

Example 2

Input: matrix = [[3, 7, 1], [9, 5, 2], [4, 8, 6]]

Output: [[4, 9, 3], [8, 5, 7], [6, 2, 1]]

The left column, read bottom to top, becomes the top row: 4, 9, 3.

Example 3

Input: matrix = [[6]]

Output: [[6]]

A single cell looks the same after any turn.

  • 1 ≤ n ≤ 20
  • −1,000 ≤ matrix[i][j] ≤ 1,000
  • The grid is square: n rows and n columns.
Clockwise or counterclockwise?
Clockwise. The top row becomes the right column.
Must it be in place?
Yes. The grid itself must change, so the best answer uses no second grid.
Is the grid always square?
Yes, n × n. A turn of a non-square grid would change its shape.
Where does matrix[i][j] go?
To row j, column n − 1 − i.

Rotation looks like a hard move, but it breaks into two easy ones. A transpose flips the grid across its main diagonal, so rows become columns. Reversing each row then mirrors it left to right. Both are plain swaps of two cells, so they need no extra grid.

Rotating four cells at a time, ring by ring, also works in place with the same Big O. Transpose and reverse is easier to get right.

Transpose, then reverse O(n²), O(1) space

Two moves in a row give a clockwise turn.

  1. Transpose: swap matrix[i][j] with matrix[j][i] for every cell above the diagonal. Now row i holds column i of the original, read top to bottom.
  2. Reverse each row. A clockwise turn needs each original column read bottom to top, so flip every row.

Why it is correct: the transpose sends [i][j] to [j][i]. Reversing row j then sends column i to column n − 1 − i. Together, [i][j] ends at [j][size − 1 − i], which is exactly a clockwise turn.

c0c1c2c3
r010111213
r114151617
r218192021
r322232425
  1. for i in range(size):
  2. for j in range(i + 1, size):
  3. matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
  4. for row in matrix:
  5. row.reverse()

Two moves give a clockwise turn: transpose (flip across the main diagonal), then reverse each row. Both work in place.

1 / 13
Solution.javasolution.pySolution.cssolution.gosolution.ts
class Solution {
// Transpose, then reverse each row: together they send [i][j] to [j][size - 1 - i].
// Every cell moves once: O(n^2) time and O(1) extra memory.
public void rotate(int[][] matrix) {
int size = matrix.length;
// j starts above the diagonal, so each pair is swapped once, not twice.
for (int i = 0; i < size; i++) {
for (int j = i + 1; j < size; j++) {
int temporary = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temporary;
}
}
// Row i now holds column i top to bottom. Clockwise needs it bottom to top.
for (int[] row : matrix) {
for (int left = 0, right = size - 1; left < right; left++, right--) {
int temporary = row[left];
row[left] = row[right];
row[right] = temporary;
}
}
}
}
Time O(n²)Space O(1)Here is how we get these from the code, in four steps.
  1. 1 Find the work that repeats

    Two parts repeat. The transpose swaps one pair per run, inside two loops. The reverse swaps pairs inside each row. One swap is 1 step.

    1. for i in range(size):
    2. for j in range(i + 1, size):
    3. matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
    4. for row in matrix:
    5. row.reverse()
  2. 2 Count the runs on Example 1

    Example 1 is 4 × 4. The transpose swaps each pair above the diagonal once: 6 swaps. Each of the 4 rows takes 2 swaps to reverse: 8 swaps.

    6 + 8 = 14 swaps.

    parttransposereverse rows
    swaps68
    total
    6 + 8 = 14
  3. 3 Write the count for any n

    Above the diagonal there are n × (n − 1) / 2 cells. Each row reverse takes n / 2 swaps:

    n(n − 1)/2 + n × n/2 = n² − n/2

    Check it with Example 1: 16 − 2 = 14.

  4. 4 Keep only the part that grows fastest

    Drop the − n/2. What is left is n², the same as the copy, but with no second grid.

    So the time is O(n²).

  5. S Space: count the extra memory the same way

    The code keeps only i and j, and the swaps use one temporary value. The space is O(1).

    ij

2,000 random grids from 1 x 1 to 6 x 6, odd and even sizes, with many repeated values. Copy to a new grid and transpose, then reverse gave the same answer every time.

Largest inputsResult
A 20 x 20 grid (the most allowed), every value different. Transpose, then reverse.Under 0.001 s, and under 0.001 MB of extra memory: swaps in place, no new rows.
The same grid. Copy to a new grid.Under 0.001 s, and about 0.005 MB: a full second grid of 400 values.