给你一幅由 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]
]
分析:
方法1:辅助数组
由示例可以看出,第 i 行的数据变成了第 n - i - 1 列的数据,即 matrix[ j ][ n - i - 1 ] = 原matrix[ i ][ j ],因此我们可以创建一个辅助数组存储旋转之后的数据,再将辅助数组的数据复制回原数组。
时间复杂度:O(n^2)
空间复杂度:O(n^2)
class Solution {
public void rotate(int[][] matrix) {
//获取边长
int len = matrix.length;
//创建结果矩阵
int[][] res = new int[len][len];
//遍历矩阵
for(int i = 0; i < len; ++i){
for(int j = 0; j < len; ++j){
res[j][len-i-1] = matrix[i][j];
}
}
//复制
for(int i = 0; i < len; ++i){
for(int j = 0; j < len; ++j){
matrix[i][j] = res[i][j];
}
}
}
}
方法2:原数组旋转
如果直接按照方法 1 的公式进行交换的话,毫无疑问会被覆盖掉一部分,那要是我们换一种方式交换呢?那以下矩阵举例:
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
按右对角线交换:
1 | 5 | 9 | 13 |
2 | 6 | 10 | 14 |
3 | 7 | 11 | 15 |
4 | 8 | 12 | 16 |
再左右交换:
13 | 9 | 5 | 1 |
14 | 10 | 6 | 2 |
15 | 11 | 7 | 3 |
16 | 12 | 8 | 4 |
这样就可以得到一个旋转90°的矩阵,对角线交换就是 matrix[ i ][ j ] 与 matrix[ j ][ i ] 交换,左右交换就是 matrix[ i ][ j ] 与 matrix[ i ][n - j - 1] 交换。
时间复杂度:O(n^2)
空间复杂度:O(1)
class Solution {
public void rotate(int[][] matrix) {
//获取边长
int n = matrix.length;
//交换对角线
for(int i = 0; i < n; ++i){
for(int j = i; j < n; ++j){
swap(i, j, j, i, matrix);
}
}
//交换左右
for(int i = 0; i < n; ++i){
for(int j = 0; j < n / 2; ++j){
swap(i, j, i, n - j - 1, matrix);
}
}
}
//交换
public void swap(int i, int j, int x, int y, int[][] matrix){
int temp = matrix[i][j];
matrix[i][j] = matrix[x][y];
matrix[x][y] = temp;
}
}
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotate-matrix-lcci