题目描述:
给定一个
n×n
的2D矩阵,将其顺时针旋转90度。不能开辟新的矩阵空间
example:
given input matrix=
[
[1,2,3],
[4,5,6],
[7,8,9]
]
rotate the input matrix in place that it becomes:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
分析
以矩阵的(0,0)为坐标系原点建立坐标系,在此坐标系中有点 (i,j) ,经过顺时针90°旋转之后,坐标系变化成右图。那么相对于原来的坐标系来说,点的坐标变成了 (j,n−1−i)
- 横纵坐标范围均为 [0,n−1]
- 根据上面右边的图可知,新点纵坐标为
j
,而横坐标为
n−1−i
分析可知:顺时针旋转90°,使得矩阵中的点的位置进行了如下变换:
(i,j)→(j,n−i−1)
不能开辟新空间,意味着一次不能修改多个矩阵的值:因为被修改的 (i,j) 都需要被存储下来
解题
针对
n×n
矩阵,每次只修改以
(i,i)
为顶点的正方形的外圈。如下图所示:
- 修改以 (i,i) 为顶点的一圈
- 按照修改规则有点的移动:
(i,j)→(j,n−i−1)→(n−i−1,n−j−1)→(n−j−1,i),即M[n−j−1][i]=M[n−i−1][n−j−1]M[n−i−1][n−j−1]=M[j][n−i−1]M[j][n−j−1]=M[i][j]M[i][j]=M[n−j−1][i]
-
注意
上面最后一步中的 M[n−j−1][i] 已经在第一步中改变了,所以在变换开始前应该保存其值。
而j只需要在上图中深色阴影范围内即可,上面的四个变换就包含了四条边,也就是说::j∈[i,n−1−i)
注意:
i
标识这我们每次得到一个以
编码
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
#(i,j)变成了(j,n-i-1)
n = len(matrix)
for i in range(int(math.floor(n/2+0.5))):
for j in range(i,n-i-1):
#旋转一圈
a=matrix[n-j-1][i]
matrix[n-j-1][i]=matrix[n-i-1][n-j-1]
matrix[n - i - 1][n - j - 1]=matrix[j][n-i-1]
matrix[j][n - i - 1]=matrix[i][j]
matrix[i][j]=a