持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
模拟
模拟矩阵的生成。按照要求,初始位置设为矩阵的左上角,初始方向设为向右。若下一步的位置超出矩阵边界,或者是之前访问过的位置,则顺时针旋转,进入下一个方向。如此反复直至填入 个元素。
记 为生成的矩阵,其初始元素设为 。由于填入的元素均为正数,我们可以判断当前位置的元素值,若不为 ,则说明已经访问过此位置。
var generateMatrix = function(n) {
const maxNum = n * n;
let curNum = 1;
const matrix = new Array(n).fill(0).map(() => new Array(n).fill(0));
let row = 0, column = 0;
const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]; // 右下左上
let directionIndex = 0;
while (curNum <= maxNum) {
matrix[row][column] = curNum;
curNum++;
const nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
if (nextRow < 0 || nextRow >= n || nextColumn < 0 || nextColumn >= n || matrix[nextRow][nextColumn] !== 0) {
directionIndex = (directionIndex + 1) % 4; // 顺时针旋转至下一个方向
}
row = row + directions[directionIndex][0];
column = column + directions[directionIndex][1];
}
return matrix;
};
按层模拟
可以将矩阵看成若干层,首先填入矩阵最外层的元素,其次填入矩阵次外层的元素,直到填入矩阵最内层的元素。
定义矩阵的第 层是到最近边界距离为 的所有顶点。例如,下图矩阵最外层元素都是第 层,次外层元素都是第 层,最内层元素都是第 层。
[[1, 1, 1, 1, 1, 1],
[1, 2, 2, 2, 2, 1],
[1, 2, 3, 3, 2, 1],
[1, 2, 3, 3, 2, 1],
[1, 2, 2, 2, 2, 1],
[1, 1, 1, 1, 1, 1]]
对于每层,从左上方开始以顺时针的顺序填入所有元素。假设当前层的左上角位于 ,右下角位于,按照如下顺序填入当前层的元素。
- 从左到右填入上侧元素,依次为 到 。
- 从上到下填入右侧元素,依次为 到 。
- 如果 且 ,则从右到左填入下侧元素,依次为 到 ,以及从下到上填入左侧元素,依次为 到 。
填完当前层的元素之后,将 和 分别增加 ,将 和 分别减少 ,进入下一层继续填入元素,直到填完所有元素为止。
var generateMatrix = function(n) {
let num = 1;
const matrix = new Array(n).fill(0).map(() => new Array(n).fill(0));
let left = 0, right = n - 1, top = 0, bottom = n - 1;
while (left <= right && top <= bottom) {
for (let column = left; column <= right; column++) {
matrix[top][column] = num;
num++;
}
for (let row = top + 1; row <= bottom; row++) {
matrix[row][right] = num;
num++;
}
if (left < right && top < bottom) {
for (let column = right - 1; column > left; column--) {
matrix[bottom][column] = num;
num++;
}
for (let row = bottom; row > top; row--) {
matrix[row][left] = num;
num++;
}
}
left++;
right--;
top++;
bottom--;
}
return matrix;
};