一、题目内容 中等
给一个正整数 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 = 0let 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] = countreturn result};
四、其他解法
输入: