这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战
前言
力扣第四十八题 旋转图像 如下所示:
给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。
示例 1:
示例 2:
一、思路
这一题最难的一点就是需要原地旋转图像,也就是说只能使用常数级的额外空间来实现转换。
实现思路主要分为以下两个部分:
- 分圈转换,从外至内:如
4 x 4的矩阵,共有两圈 - 某一圈交换时,只关注前
n- 1 - i个元素,且每个元素需要交换三次
图解原地旋转
以 matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]] 作为例子讲述
分圈转换,从外至内
这个 4 x 4 的矩阵只有两个圈,我们只需要处理这两个圈即可
某一圈交换时
此处以外圈 ①号圈 作为例子
我们只需要关注圈中的 5, 1, 9 即可
具体的交换逻辑如下所示(仅以第一个元素作为例子):
- 交换
matrix[0][0]和matrix[0][3]
- 交换
matrix[0][0]和matrix[3][3]
- 交换
matrix[0][0]和matrix[3][0]
交换的规律
交换的规律我做了以下总结:
- 以圈中的前
n - 1- i个元素作为基准 - 某一个点需要交换三次,三个点的特征如下:
- 交换的第一个点:列固定
- 交换的第二个点:行固定
- 交换的第三个点:列固定
二、实现
实现代码
实现代码与思路中保持一致
public void rotate(int[][] matrix) {
int n = matrix.length;
// nxn 的二维数组需要旋转 n-2 次(n>2)
for (int i=0; i == 0 || i<n-2; i++) {
int end = n- 1 - i;
// 每一圈需要置换多少个点为 n-2*i-1
for (int j=0; j<n-2*i-1; j++) {
// 每个点值需要置换三次
for (int m=0; m<3; m++) {
int temp = matrix[i][i+j];
if (m==0) { // 替换第一个数(列固定)
matrix[i][i+j] = matrix[i + j][end];
matrix[i + j][end] = temp;
} else if (m==1){ // 替换第二个数(行固定)
matrix[i][i+j] = matrix[end][end - j];
matrix[end][end - j] = temp;
} else { // 替换第三个数(列固定)
matrix[i][i+j] = matrix[end - j][i];
matrix[end - j][i] = temp;
}
}
}
}
}
测试代码
public static void main(String[] args) {
int[][] matrix = {{5,1,9,11},{2,4,8,10},{13,3,6,7},{15,14,12,16}};
int[][] matrix1 = {{1,2},{3,4}};
new Number48().rotate(matrix1);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥