旋转图像

标签: 数组 数学 矩阵

难度: Medium

给定一个 × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

Submission

运行时间: 44 ms

内存: 14.8 MB

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        # 转置
        n = len(matrix)
        for i in range(n):
            for j in range(i, n):
                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

        # 每一行反转
        for i in range(n):
            matrix[i] = matrix[i][::-1]



Explain

这个题解采用了两步操作来实现矩阵的顺时针旋转90度。第一步是将矩阵进行转置,即将矩阵的行列进行互换。第二步是将转置后的矩阵的每一行进行反转。经过这两步操作,原矩阵就被顺时针旋转了90度。这种方法可以在原地修改矩阵,不需要使用额外的矩阵空间。

时间复杂度: O(n^2)

空间复杂度: O(1)

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        n = len(matrix)
        
        # 第一步:转置矩阵
        for i in range(n):
            for j in range(i, n):
                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
        
        # 第二步:反转每一行
        for i in range(n):
            matrix[i] = matrix[i][::-1]

Explore

在顺时针旋转图像时,首先选择转置矩阵是为了简化旋转操作。通过转置,原矩阵的行变成了列,这样只需要进行行的反转即可完成顺时针旋转。如果不先转置,将需要复杂的坐标映射来直接实现旋转,这不仅编程复杂,而且容易出错。转置和行反转的组合使得代码更简洁、易于理解,并且可以在原地完成,不需要额外空间。

在转置矩阵的过程中,只遍历上三角区域是为了避免重复交换元素。如果遍历整个矩阵进行元素交换,每个元素会被交换两次,最终导致矩阵未发生任何改变。通过限制在上三角区域,每对元素只交换一次,确保每个元素都正确地移动到其转置位置。

将转置后的矩阵的每一行反转主要是为了完成90度旋转,这个操作改变了矩阵的行列对应关系,从而改变了矩阵的行列对称性。而且,该操作会导致原本对称或者非对称的矩阵失去其原有的对称特性。因此,可以说这种操作改变了矩阵的某些属性,如对称性。

在这种旋转操作中,所有的操作都是在原矩阵的尺寸范围内完成的。转置操作改变了元素的行列位置但保持在原矩阵的边界内,行反转也同样只是改变了元素在行内的顺序而已。因此,不会有任何行或列超出原始矩阵的边界。这个旋转操作是完全在原矩阵的尺寸范围内进行的。