48. Rotate Image
一、题目
Problem Description:
You are given an
n
x
n
n x n
nxn 2D matrix representing an image, rotate the image by 90 degrees (clockwise).
You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.
Example 1:
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [[7,4,1],[8,5,2],[9,6,3]]
Example 2:
Input: matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
Output: [[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
Example 3:
Input: matrix = [[1]]
Output: [[1]]
Example 4:
Input: matrix = [[1,2],[3,4]]
Output: [[3,1],[4,2]]
Constraints:
m
a
t
r
i
x
.
l
e
n
g
t
h
=
=
n
matrix.length == n
matrix.length==n
m
a
t
r
i
x
[
i
]
.
l
e
n
g
t
h
=
=
n
matrix[i].length == n
matrix[i].length==n
1
<
=
n
<
=
20
1 <= n <= 20
1<=n<=20
−
1000
<
=
m
a
t
r
i
x
[
i
]
[
j
]
<
=
1000
-1000 <= matrix[i][j] <= 1000
−1000<=matrix[i][j]<=1000
二、题解
给定一个
n
∗
n
n*n
n∗n的二维数组表示一张图像,将图像顺时钟旋转90°,输出旋转后的二维数组。
注:要求原地旋转,即要求解题的空间复杂度为
O
(
1
)
O(1)
O(1)
2.1 Approach #1 : Reverse and Transpose
此方法利用数学小知识,通过上下翻转、左右翻转、对角线翻转等,最终实现顺时针旋转90°。
下图四种方法都可以实现顺时针旋转90°操作。
下面代码以图中的方法一为例,即“先上下翻转,再对角线(左上–右下)翻转”。
Time complexity :
O
(
n
2
)
O(n^2)
O(n2).
Space complexity :
O
(
1
)
O(1)
O(1).
//Reverse and Transpose
//Time complexity : O(n^2); Space complexity : O(1)
class Solution {
public void rotate(int[][] matrix) {
int n = matrix.length;
//上下翻转
for(int i = 0; i < n / 2; i++){
for(int j = 0; j < n; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[n-1-i][j];
matrix[n-1-i][j] = temp;
}
}
//对角线(左上--右下)翻转
for(int i = 0; i < n; i++){
for(int j = i + 1; j < n; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
}
}
2.2 Approach #2 : Rotate four rectangles
要想将图像顺时针旋转90°,其实就是将矩阵的各个元素点顺时针旋转90°。
n
∗
n
n*n
n∗n矩阵可以看成一个正方形,边长为4。以下图为例,圆中的4个元素各自转顺时针旋转90°形成了一个闭环。
3
∗
3
3*3
3∗3 矩阵经过以下两个闭环旋转后,即可输出最终结果。
将
n
∗
n
n*n
n∗n的原矩阵人为切割为四个矩形,上面连续两个闭环旋转可归结为对一个矩阵进行旋转。
同理
4
∗
4
4*4
4∗4矩阵可分割为以下四个矩阵。以此类推
n
∗
n
n*n
n∗n矩阵。
Time complexity :
O
(
n
2
)
O(n^2)
O(n2)
Space complexity :
O
(
1
)
O(1)
O(1)
以下代码中,用一个大小为4的数组存储一次闭环旋转的四个元素值。
//Rotate four rectangles
//Time complexity : O(n^2); Space complexity : O(1)
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[] arr = new int[4];
int row = i;
int col = j;
//matrix -> arr
for(int k = 0; k < 4; k++){
arr[k] = matrix[row][col];
int temp = row;
row = col;
col = n - 1 - temp;
}
//arr -> matrix
for(int k = 0; k < 4; k++){
matrix[row][col] = arr[(k + 3) % 4];
int temp = row;
row = col;
col = n - 1 - temp;
}
}
}
}
}
以下代码中,无需再用一个大小为4的数组,直接借助一个临时变量,将闭环的四个元素值挨个赋值到顺时针旋转90°后的位置即可。
//Rotate four rectangles in one single loop
//Time complexity : O(n^2); Space complexity : O(1)
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[i][j];
matrix[i][j] = 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] = temp;
}
}
}
}