给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3
输出:
[
[ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix-ii
解题思路
受到 LeetCode-048-旋转图像 的启发
也是将矩阵每一层分割为等大的四部分
然后用两层循环, 外层循环次数为层数, 层数 = (n + 1) / 2
内层循环次数是每层等大的四部分的长度, 为 n - 层数(从0开始) * 2 - 1
四部分分别是上右下左
且规律是 右部分的第 i 个元素 = 上部分的第 i 个位置的元素 + 该层每部分长度
下部分的第 i 个元素 = 右部分的第 i 个位置的元素 + 该层每部分长度
左部分的第 i 个元素 = 下部分的第 i 个位置的元素 + 该层每部分长度
所以只需要确定每层上部分的第一个元素, 随后填满这一层
最后注意如果 n 是奇数, 需要补充最中间的数字
代码
class Solution {
public int[][] generateMatrix(int n) {
int[][] result = new int[n][n];
// 层数 = (n + 1) / 2
int layer = (n + 1) / 2;
// 填的数字
int num = 1;
for (int i = 0; i < layer; i++) {
// 每一层分成四部分, 每部分的长度
int partLength = n - i * 2 - 1;
int start = num;
for (int j = 0; j < partLength; j++) {
// result[i][i + j] 上
// result[i + j][n - i - 1] 右
// result[n - i - 1][n - i - 1 - j] 下
// result[n - i - 1 - j][i] 左
result[i][i + j] = start + j;
result[i + j][n - i - 1] = result[i][i + j] + partLength;
result[n - i - 1][n - i - 1 - j] = result[i + j][n - i - 1] + partLength;
result[n - i - 1 - j][i] = result[n - i - 1][n - i - 1 - j] + partLength;
}
// 下一层的起始数字
num = num + partLength * 4;
}
// 如果n是奇数, 还需要补上最中间的元素
if ((n & 0x1) == 0x1) {
result[n / 2][n / 2] = n * n;
}
return result;
}
}