目标
给你一个大小为 m x n 的整数矩阵 grid ,其中 m 和 n 都是 偶数 ;另给你一个整数 k 。
矩阵由若干层组成,如下图所示,每种颜色代表一层:

矩阵的循环轮转是通过分别循环轮转矩阵中的每一层完成的。在对某一层进行一次循环旋转操作时,层中的每一个元素将会取代其 逆时针 方向的相邻元素。轮转示例如下:

返回执行 k 次循环轮转操作后的矩阵。
示例 1:

输入:grid = [[40,10],[30,20]], k = 1
输出:[[10,20],[40,30]]
解释:上图展示了矩阵在执行循环轮转操作时每一步的状态。
示例 2:



输入:grid = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]], k = 2
输出:[[3,4,8,12],[2,11,10,16],[1,7,6,15],[5,9,13,14]]
解释:上图展示了矩阵在执行循环轮转操作时每一步的状态。
说明:
- m == grid.length
- n == grid[i].length
- 2 <= m, n <= 50
- m 和 n 都是 偶数
- 1 <= grid[i][j] <= 5000
- 1 <= k <= 10^9
思路
有一个 m x n 矩阵 grid,m 与 n 都是偶数,矩阵里外分层,每次轮转用元素取代对应层逆时针方向的下一个元素,求轮转 k 次之后的矩阵。
m x n 矩阵有 Math.min(m/2, n/2) 层,最外层有 2 * (m + n) - 4 个元素,下一层用 m - 2, n - 2 代入,得到比上一层少 8 个元素,以此类推。
将每一层映射到一维进行轮转,然后再赋值回去即可。可以使用方向向量来赋值,碰到边界就转向。
参考 874.模拟行走机器人 2069.模拟行走机器人II 59.螺旋矩阵II
代码
/**
* @date 2026-05-09 9:26
*/
public class RotateGrid1914 {
public int[][] rotateGrid(int[][] grid, int k) {
int m = grid.length;
int n = grid[0].length;
int layer = Math.min(m / 2, n / 2);
int[][] arr = new int[layer][];
int length = 2 * (m + n) - 4;
int[][] directions = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
for (int i = 0, x = 0, y = 0, d = 0; i < layer; i++, x++, y++) {
arr[i] = new int[length];
int a = x, b = y;
for (int j = 0; j < length; j++) {
arr[i][j] = grid[a][b];
while (a + directions[d][0] < x || a + directions[d][0] > m - 1 - x
|| b + directions[d][1] < y || b + directions[d][1] > n - 1 - y) {
d = (d + 1) % 4;
}
a += directions[d][0];
b += directions[d][1];
}
int offset = k % length;
a = x;
b = y;
d = 0;
for (int j = offset; j < offset + length; j++) {
grid[a][b] = arr[i][j % length];
while (a + directions[d][0] < x || a + directions[d][0] > m - 1 - x
|| b + directions[d][1] < y || b + directions[d][1] > n - 1 - y) {
d = (d + 1) % 4;
}
a += directions[d][0];
b += directions[d][1];
}
length -= 8;
}
return grid;
}
}
性能
















