59.螺旋矩阵II
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
思路
当 n = 3 时,矩阵如下图所示:
仔细观察这个矩阵,可以假设有一个人需要按顺序依次经过矩阵中的表格,那么他就需要先往左走两步,再往下走两步,再从右往左走两步,最后从下往上走两步。
如下图所示:
需要仔细考虑的其实是边界问题,上面说当 n = 3 时,每次走两步,那么当 n = 4 时呢?
其实可以将多少步的问题转换为终点坐标和起点坐标。
起点坐标从 0 开始,每一圈走完加 1。
终点坐标第一圈在 n - 2 结束,每一圈走完减一。
代码
var generateMatrix = function(n) {
let startX = startY = 0; // 起始位置
let loop = Math.floor(n/2); // 旋转圈数
let mid = Math.floor(n/2); // 中间位置
let offset = 1; // 控制每一层填充元素个数
let count = 1; // 更新填充数字
let res = new Array(n).fill(0).map(() => new Array(n).fill(0));
while (loop--) {
let row = startX, col = startY;
// 上行从左到右(左闭右开)
for (; col < n - offset; col++) {
res[row][col] = count++;
}
// 右列从上到下(左闭右开)
for (; row < n - offset; row++) {
res[row][col] = count++;
}
// 下行从右到左(左闭右开)
for (; col > startY; col--) {
res[row][col] = count++;
}
// 左列做下到上(左闭右开)
for (; row > startX; row--) {
res[row][col] = count++;
}
// 更新起始位置
startX++;
startY++;
// 更新offset
offset += 1;
}
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
if (n % 2 === 1) {
res[mid][mid] = count;
}
return res;
};