Rotate Matrix
Given a square n x n matrix of integers matrix, rotate it by 90 degrees clockwise.
You must rotate the matrix in-place. Do not allocate another 2D matrix and do the rotation.
Example 1:
Input: matrix = [
[1,2],
[3,4]
]
Output: [
[3,1],
[4,2]
]
Example 2:
Input: matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
]
Output: [
[7,4,1],
[8,5,2],
[9,6,3]
]
Constraints:
n == matrix.length == matrix[i].length
1 <= n <= 20
-1000 <= matrix[i][j] <= 1000
Solution
The most difficult part of this problem is that we cannot allocate another n 2 n^2 n2 space to do a direct rotate. Noticing that an element at matrix ( i , j ) (i,j) (i,j) will move to ( j , n − i − 1 ) (j, n-i-1) (j,n−i−1), ( j , n − i − 1 ) (j, n-i-1) (j,n−i−1) will move to ( n − i − 1 , n − j − 1 ) (n-i-1, n-j-1) (n−i−1,n−j−1), ( n − i − 1 , n − j − 1 ) (n-i-1, n-j-1) (n−i−1,n−j−1) will move to ( n − j − 1 , i ) (n-j-1, i) (n−j−1,i) and ( n − j − 1 , i ) (n-j-1, i) (n−j−1,i) will move to ( i , j ) (i,j) (i,j) after rotation. Four elements consist of a loop and one rotation of the loop can be completed in O ( 1 ) O(1) O(1) extra space.
For example, for matrix rotation
[
a
b
c
d
]
⟶
[
c
a
d
b
]
\left[\begin{array}{l} a & b\\ c & d\\ \end{array} \right] \longrightarrow \left[\begin{array}{l} c & a\\ d & b\\ \end{array} \right]
[acbd]⟶[cdab]
we can swap
a
,
b
a, b
a,b first, then swap
b
,
c
b, c
b,c, finally swap
b
,
d
b, d
b,d. The process looks like:
[
a
b
c
d
]
→
[
b
a
c
d
]
→
[
c
a
b
d
]
→
[
c
a
d
b
]
\left[\begin{array}{l} a & b\\ c & d\\ \end{array} \right] \rightarrow \left[\begin{array}{l} b & a\\ c & d\\ \end{array} \right] \rightarrow \left[\begin{array}{l} c & a\\ b & d\\ \end{array} \right] \rightarrow \left[\begin{array}{l} c & a\\ d & b\\ \end{array} \right]
[acbd]→[bcad]→[cbad]→[cdab]
So, 3 times’ swap can solve 1 loop, we just need to find out all the start elements of loops in the matrix. Basically, the coordinates of start points are
∑
i
=
0
n
−
2
∑
j
=
i
n
−
2
−
i
\sum_{i=0}^{n-2}\sum_{j=i}^{n-2-i}
∑i=0n−2∑j=in−2−i, corresponding to the area of an isosceles right triangle with the upper side of the matrix as the hypotenuse.
Code
If you figure out the regulations above clearly, the code is rather easy.
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
length = len(matrix)
for i in range(length-1):
for j in range(i, length-i-1):
matrix[i][j], matrix[j][length-i-1] = matrix[j][length-i-1], matrix[i][j]
matrix[i][j], matrix[length-j-1][i] = matrix[length-j-1][i], matrix[i][j]
matrix[length-j-1][i], matrix[length-i-1][length-j-1] = matrix[length-i-1][length-j-1], matrix[length-j-1][i]