【Leetcode】48. 旋转图像

154 阅读3分钟

题目描述

在这里插入图片描述

// 48. 旋转图像

// 给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

// 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用
// 另一个矩阵来旋转图像。

题解

// 假设长度为len*len的矩阵。
// 旋转前
// 1       2       3       4

// 5       6       7       8

// 9       10      11      12

// 13      14      15      16

// 旋转后
// 13      9       5      1

// 14      10      6      2

// 15      11      7      3

// 16      12      8      4


// 分组
// 1        2        3        4

// 5                          8

// 9                          12

// 13      14       15        16

// 我们的思路是,先旋转外圈元素,再慢慢缩圈把内圈元素旋转过来,
// 而在圈中的旋转我们又采取分组的策略,一组一组元素地旋转过来。
// 所有组旋转过来,一圈元素就旋转好了,所有圈的元素旋转好了,
// 整个矩阵就旋转好了。

// 可以发现在外圈中:
// [0, 0], [0, len-1], [len-1, len-1], [len-1, 0] 为第一组
// [0, 1], [1, len-1], [len-1, len-2], [len-2, 0] 为第二组
// [0, 2], [2, len-1], [len-1, len-3], [len-3, 0] 为第三组
//  i  j    j len-1-i  len-1-i len-1-j  len-1-j i

// 可以重写为:
// [i, j], [j, len-1-i], [len-1-i, len-1-j], [len-1-j, i] 为第一组
// [i, j], [j, len-1-i], [len-1-i, len-1-j], [len-1-j, i] 为第二组
// [i, j], [j, len-1-i], [len-1-i, len-1-j], [len-1-j, i] 为第三组
// 可以发现 i∈[0, (len-1)/2],j∈[0, jborder],i的范围就是从外圈慢慢往内缩圈的
// 过程。而j的范围就是不同组的移动的范围,其中jborder为j能够移动的右边界,实例中
// 我们以matrix[i][j]为例子,最外圈j能够移动到2(最右位置再往左一格),
// 所以jborder初始化为jborder=len-2=2,内圈j能够只能够走到1,
// 所以jborder -= 1 = 1。可以看到每次缩圈,jborder
// 都会累减一次。所以循环之后将jborder累减1就行,很容易维护这个jborder边界。
// 
// 取matrix的边长len,如果len为0直接返回,初始化j的边界jborder为len-2,
// 第一个for循环编写缩圈索引i的缩圈过程,
// 第二个for循环编写不同组之间的索引j的遍历过程,
// 因为是顺时针旋转,所以赋值的方向是逆时针的,
// 先把matrix[j][len-1-i](右上)存入temp,我们要把matrix[i][j](左上)
// 存入matrix[j][len-1-i](右上) 则有:matrix[j][len-1-i] = matrix[i][j],
// 这个时候matrix[i][j](左上)已经被使用过了,matrix[i][j]中的元素可以被替换了,
// 逆时针取上一个元素matrix[len-1-j][i](左下),将matrix[len-1-j][i](左下)
// 存入matrix[i][j](左上)。
// 这时候matrix[len-1-j][i](左下)已经使用过了,可以被替换,
// 我们再逆时针取上一个元素matrix[len-1-i][len-1-j](右下),
// 把它存入matrix[len-1-j][i](左下),这时候matrix[len-1-i][len-1-j](右下)
// 元素已经被使用了,我们将temp中的左上角元素存入matrix[len-1-i][len-1-j],
// 这一圈的第一组元素就完成了旋转。其他组其他圈同理。

// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:38.6 MB, 在所有 Java 提交中击败49.72%的用户
class Solution {
    public void rotate(int[][] matrix) {
		int len = matrix.length;
		if (len == 0)
			return;
		int jborder = len - 2;
		for (int i = 0; i <= (len - 1)/2; i++) {
			for (int j = i; j <= jborder; j++) {
				int temp = matrix[j][len-1-i];
				matrix[j][len-1-i] = matrix[i][j];
				matrix[i][j] = matrix[len-1-j][i];
				matrix[len-1-j][i] = matrix[len-1-i][len-1-j];
				matrix[len-1-i][len-1-j] = temp;
			}
			jborder -= 1;
		}
    }
}