题目描述
给你一幅由 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(1)
拓展
上面的代码解决的是矩阵顺时针旋转 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)
- 空间复杂度:O(n)