一、题目内容 中等
给一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的n x n
正方形矩阵matrix
示例1:
输入:
n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例2:
输入:
n = 1
输出:[[1]]
提示:
由外向内一圈一圈这么画下去。
可以发现这里的边界条件非常多,在一个循环中,如此多的边界条件,如果不按照固定规则来遍历,那就是一进循环深似海,从此 offer 是路人。
这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。
那么我按照左闭右开的原则,来画一圈,大家看一下:
这里每一种颜色,代表一条边,我们遍历的长度,可以看出每一个拐角处的处理规则,拐角处让给新的一条边来继续画。
这也是坚持了每条边左闭右开的原则。
-
三、具体代码
/**
* @param {number} n
* @return {number[][]}
*/
var generateMatrix = function (n) {
const result = new Array(n).fill(1).map(_ => new Array(n).fill(1))
let startx = 0, starty = 0
let loop = Math.floor(n / 2) // 循环几圈
let count = 1 // 填充的数字
let offset = 1 // 控制遍历时,边界的范围
const mid = n % 2 ? Math.floor(n / 2) : 0 // 圈的中心,如果是奇数就需要填充
while (loop--) {
// 从左到右填充,左开右闭
for (; startx < n - offset; startx++) {
result[starty][startx] = count++
}
// 从上到下填充,左开右闭
for (; starty < n - offset; starty++) {
result[starty][startx] = count++
}
// 从右到左填充,左开右闭
for (; startx > offset - 1; startx--) {
result[starty][startx] = count++
}
// 从下到上填充,左开右闭
for (; starty > offset - 1; starty--) {
result[starty][startx] = count++
}
startx++
starty++
offset++
}
if (mid !== 0) result[mid][mid] = count
return result
};
四、其他解法