【LeetCode-数组】旋转矩阵(顺时针/逆时针)

题目描述

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

不占用额外内存空间能否做到?
示例:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]

题目链接: https://leetcode-cn.com/problems/rotate-matrix-lcci/

思路1

原地旋转。将矩阵顺时针旋转 90 度可以分解为两个步骤:

  • 将矩阵按照主对角线(左上~右下)反转;
  • 将矩阵的每一行按照中点进行反转;

代码如下:

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        if(matrix.empty()) return;

        int n = matrix.size();
        for(int i=0; i<n; i++){  //按照主对角线翻转
            for(int j=0; j<i; j++){
                swap(matrix[i][j], matrix[j][i]);
            }
        }

        for(int i=0; i<n; i++){  // 每一行按照中点进行翻转
            for(int j=0; j<n/2; j++){
                swap(matrix[i][j], matrix[i][n-j-1]);
            }
        }
    }
};
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)

思路2

使用额外空间。我们对比旋转前后的两个矩阵发现:旋转前的第 1 行变成了旋转后的倒数第 1 列、旋转前的第 2 行变成了旋转后的倒数第 2 列,也就是旋转前的第 i 行变成了旋转后的倒数第 n-i-1 列,i∈[0, n-1]。代码如下:

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        if(matrix.empty()) return;

        int n = matrix.size();
        vector<vector<int>> copy(n, vector<int>(n, 0));
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                copy[j][n-i-1] = matrix[i][j];
            }
        }
        matrix = copy;
    }
};
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n^2)

拓展

上面的代码解决的是矩阵顺时针旋转 90 度,如果是逆时针旋转 90 度,则也可以分为两个步骤:

  • 将矩阵按照次对角线(左下~右上)反转;
  • 将矩阵的每行按照中点反转;

假设矩阵次对角线上面区域的一个元素位置为 (i, j),假设 (i, j) 以次对角线对称的位置为 (a, b),因为 i+a=n-1,j+b=n-1,所以 (i, j) 根据次对角线对称的位置为 (n-i-1, n-j-1)。代码如下:

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        if(matrix.empty()) return;

        int n = matrix.size();
        for(int i=0; i<n; i++){  // 次对角线翻转
            for(int j=0; j<n-i; j++){
                swap(matrix[i][j], matrix[n-j-1][n-i-1]);
            }
        }
        
        for(int i=0; i<n; i++){  // 每行按照中点翻转
            for(int j=0; j<n/2; j++){
                swap(matrix[i][j], matrix[i][n-j-1]);
            }
        }
    }
};
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)
posted @ 2020-08-17 10:36  Flix  阅读(3442)  评论(0编辑  收藏  举报