leetcode-旋转矩阵

 题目来自LeetCode,链接:面试题 01.07. 旋转矩阵。具体描述为:给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 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]
]

 首先先用需要额外空间的方法,也就是用一个额外矩阵存储一个备份,然后再将旋转后矩阵给赋值到原矩阵中去。那么这个旋转之后的索引与旋转之前的索引之间的关系是咋样的呢,首先需要定义原点在矩阵的中间mid=(N-1)/2,然后每个元素的坐标就是(i-mid, j-mid),利用旋转矩阵
( c o s α s i n α s i n α c o s α ) \begin{pmatrix} cos\alpha & sin\alpha\\ -sin\alpha & cos\alpha \end{pmatrix}
α = 90 ° \alpha=90\degree 可以得到每个元素旋转后的坐标变为了
( 0 1 1 0 ) ( i m i d j m i d ) = ( j m i d m i d j ) \begin{pmatrix} 0 & 1\\ -1 & 0 \end{pmatrix} \cdot \begin{pmatrix} i-mid\\ j-mid \end{pmatrix} =\begin{pmatrix} j-mid\\ mid-j \end{pmatrix}
所以真正在矩阵中的索引就是
( j m i d m i d j ) + m i d = ( j 2 × m i d j ) = ( j N 1 j ) \begin{pmatrix} j-mid\\ mid-j \end{pmatrix} +mid =\begin{pmatrix} j\\ 2\times mid-j \end{pmatrix} =\begin{pmatrix} j\\ N-1-j \end{pmatrix}

 这种利用额外空间的方法的时间复杂度为 O ( N 2 ) O(N^{2}) ,空间复杂度为 O ( N 2 ) O(N^{2})

 JAVA版代码如下:

class Solution {
    public void rotate(int[][] matrix) {
        int N = matrix.length;
        int[][] copy = new int[N][N];
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                copy[i][j] = matrix[i][j];
            }
        }
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                matrix[j][N - 1 - i] = copy[i][j];
            }
        }
    }
}

 提交结果如下:


 接着是原地操作的方法,考虑到旋转过程中有四个元素是成环的,也就是第一个旋转到第二个的位置,第二个旋转到第三个的位置,第三个旋转到第四个的位置,第四个旋转到第一个的位置,如下用坐标表示更加清楚:
( i j ) ( j N 1 i ) ( N 1 i N 1 j ) ( N 1 j i ) ( i j ) \begin{pmatrix} i\\ j \end{pmatrix} \to\begin{pmatrix} j\\ N-1-i \end{pmatrix} \to\begin{pmatrix} N-1-i\\ N-1-j \end{pmatrix} \to\begin{pmatrix} N-1-j\\ i \end{pmatrix} \to\begin{pmatrix} i\\ j \end{pmatrix}

 所以可以一次到位完成这四个元素的旋转,从而可以原地操作(需要注意的是只需要遍历四分之一的(i,j))。时间复杂度还是 O ( N 2 ) O(N^{2}) ,空间复杂度则降为 O ( 1 ) O(1)

 JAVA版代码如下:

class Solution {
    public void rotate(int[][] matrix) {
        int N = matrix.length;
        for (int i = 0; i <= (N - 1) / 2; ++i) {
            for (int j = 0; j < N / 2; ++j) {
                int temp = matrix[N - 1 - j][i];
                matrix[N - 1 - j][i] = matrix[N - 1 - i][N - 1 - j];
                matrix[N - 1 - i][N - 1 - j] = matrix[j][N - 1 - i];
                matrix[j][N - 1 - i] = matrix[i][j];
                matrix[i][j] = temp;
            }
        }
    }
}

 提交结果如下:


 Python版代码如下:

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 + 1) // 2):
            for j in range(N // 2):
                temp = matrix[N - 1 - j][i]
                matrix[N - 1 - j][i] = matrix[N - 1 - i][N - 1 - j]
                matrix[N - 1 - i][N - 1 - j] = matrix[j][N - 1 - i]
                matrix[j][N - 1 - i] = matrix[i][j]
                matrix[i][j] = temp

 提交结果如下:


发布了68 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/JR_Chan/article/details/105362434
今日推荐