旋转图像

给定一个 n × n 的二维矩阵表示一个图像。

将图像顺时针旋转 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//2 为对称两两交换,然后再按对角线,交换对称元素。

这里需要值得注意的一点是,有些元素会在交换之后,再次交换,所以需要记录一下交换的位置,防止再次交换。

代码如下:

In [1]:
class Solution:
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        n = len(matrix)
        # 先交换行的每行元素, 0与n, 1与n-1两两交换
        for i in range(n):
            for j in range(n//2):
                matrix[i][j], matrix[i][n-j-1] = matrix[i][n-j-1], matrix[i][j]
        changed = set()
        # 再交换斜列元素
        for i in range(n-1):
            for j in range(n-1):
                if "{},{}".format(i, j) not in changed:
                    matrix[i][j], matrix[n-j-1][n-i-1] = matrix[n-j-1][n-i-1], matrix[i][j]
                    changed.add("{},{}".format(i, j))
                    changed.add("{},{}".format(n-j-1, n-i-1))

参考

但是这个办法只是遍历了所有元素进行交换,并不能让我满意。只好参考一下其他排名的做法。在这里列出来。

解法一

In [2]:
class Solution:
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        length = len(matrix)
        temp = [[matrix[length-1-i][j] for i in range(length)] for j in range(length)]
        for i in range(length):
            matrix[i] = temp[i]

第一种做法是计算出每个元素在移位之后的新下标位置之后构成一个新的数组,最后再将数组赋值到原数组上。

其实这种做法,并不是很符合题意,但是从效率执行上来看,使用了列表推导式来加快执行。

从题目中看,元素交换之后的位置按如下公式可得:

$$i = n - j - 1$$$$j = i$$

其中 i 为纵列, j 为横下标。我原来的思路主要是为了能够在原数组上直接交换,事先将 j 按 $j = n - j - 1$ 交换之后,再进行交换。

这里解法中使用了列表推导式来加快了一下执行效率, 大体上和我的解法还是一致的。

解法二

这里还看到一个比较有意思的解法,利用python中的高阶函数。

解法如下:

In [3]:
class Solution:
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        matrix[:] = map(list,zip(*matrix[::-1])) 

首先将数组倒序排序之后,并使用zip将纵列元素重新组成一个新的list,最后赋值。这里值得记录 :)

Comments !