59-螺旋矩阵 II
题目描述
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
示例 1:
输入: n = 3
输出: [[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入: n = 1
输出: [[1]]
分析
先初始化n*n的数组,所有的值都为0
然后遍历从1到n*n,定义一个前进方向,右下左上依次切换,切换的条件是如果按照当前方向前进的话,下一个值为undefined或者不为0的时候,则换成下一个方向。
题解
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function(matrix) {
let res = [];
let exists = [];
let m = matrix.length;
let n = matrix[0].length;
let x=y=0;
let index = 0; // 当前方向
let chioces = [
[1, 0], // 向右
[0, 1], // 向下
[-1, 0], // 向左
[0, -1], // 向上
]
for(let cnt=1; cnt<m*n+1; cnt++) {
exists.push(y*n+x);
res.push(matrix[y][x])
let newy = y+chioces[index][1]
let newx = x+chioces[index][0]
if(matrix[newy]==undefined || matrix[newy][newx]==undefined || exists.includes(newy*n+newx)) {
index = (index + 1) % 4
}
y = y+chioces[index][1]
x = x+chioces[index][0]
}
return res
};
分析
时间复杂度:O(n^2)
空间复杂度:O(1)
优化 - 代码可读性
之前用的方法是 模拟
,优化方法是 按层模拟
。相当于是不断更新边界条件。
- 从左到右填入上侧元素,依次为 (top,left) 到 (top,right)。
- 从上到下填入右侧元素,依次为 (top+1,right) 到 (bottom,right)。
- 如果 left<right 且 top<bottom,则从右到左填入下侧元素,依次为 (bottom,right−1) 到 (bottom,left+1),以及从下到上填入左侧元素,依次为 (bottom,left) 到 (top+1,left)。
填完当前层的元素之后,将 left 和 top 分别增加 1,将 right 和 bottom 分别减少 1,进入下一层继续填入元素,直到填完所有元素为止。
/**
* @param {number} n
* @return {number[][]}
*/
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 = startY; col < n - offset; col++) {
res[row][col] = count++;
}
// 右列从上到下(左闭右开)
for (row=startX; 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 ++;
}
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
if (n % 2 === 1) {
res[mid][mid] = count;
}
return res;
};
难点
模拟、螺旋打印