本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
本题采用递归的思想 对于每圈,我们可以将它分为四个部分:
若按上图x,y轴建立二维坐标系, 设正方形边长为n,则有如下对应关系
- 1 与 2 中元素对应关系为 (x, y) -> (n-1-y, x)
- 1 与 3 中元素对应关系为 (x, y) -> (n-1-x, n-1-y)
- 1 与 4 中元素对应关系为 (x, y) -> (y, n-1-x)
那么我们该如何使用这一系列的对应关系呢?
我们可以建立一个从 [0, n-1] 的循环,对于每一次枚举 1 中的元素,我们可以将其先于 2 中的对应位置交换元素的值,
那么对应 2 中的元素就成功的更新为旋转后所对应的值,此时只需继续将 (0, 0) 处更新后的值按照对应关系依次与 3、4 中的对应元素交换值,即可得到 i = 0 时枚举旋转后的二维数组:
此后仅需进行递归操作即可。
public void rotate(int[][] matrix) {
dfs(0, matrix.length-1, matrix);
}
private static void dfs(int y, int times ,int[][] matrix) {
if (times < 1) {
return;
}
int length = matrix.length-1;
for (int x = y; x < y+times; ++ x) {
int j = 0;
while (j != 4) {
switch (j) {
case 1:
swap(x, y, length-y, x, matrix);
break;
case 2:
swap(x, y, length-x, length-y, matrix);
break;
case 3:
swap(x, y, y, length-x, matrix);
break;
}
++ j;
}
}
dfs(y+1, times-2, matrix);
}
private static void swap(int x1, int y1, int x2, int y2, int[][] map) {
if (x1 == x2 && y1 == y2) return;
map[y1][x1] ^= map[y2][x2];
map[y2][x2] ^= map[y1][x1];
map[y1][x1] ^= map[y2][x2];
}
此算法时间复杂度 O(N) 空间复杂度 O(1)