笔试的时候碰到了这样一道题:
给定一个整数n,打印一个n x n的螺旋矩阵,示例如下:
n:3
输出:
[ [1,2,3],
[8,9,4],
[7,6,5]]
在笔试的时候总想着找规律,如果数学基础不太好,脑子大概很快也会变成一个小螺旋~~
在这里分享一种个人的思路,以最直观的方式解决问题,代码不一定是最简洁的,但是希望它比那些长长的公式好理解一些。
相信大家都玩过贪吃蛇,在这道题目里,我们可以把它看成一条蛇的自盘之路:是日,数组森林闯入一条皮皮蛇,它时而向右,时而向下,时而…盘住了自己,最后把自己撞死了!(全剧终 )
言归正传,我们还是来看看代码如何实现。
首先我们可以先建立一个n x n的数组,用0填满它作为我们的初始化数组,然后定义一个变量value来表示每一步我们要填在数组中的数字,用x,y来表示蛇头的位置。
let arr = new Array(n);
for (var i = 0; i < n; i++) {
var arr1 = new Array(n).fill(0);
arr[i] = arr1;
}
let value=1;
let x=0,y=0;
接下来我们可以制作一个“按钮”,利用按钮来控制“皮皮蛇”的方向,使用一个变量flag来表示下一步的前进方向,然后就可以骑蛇去自盘了~
等等!那我们怎么知道什么时候按下按钮呢?这也是这道题最关键的地方。在这道题里,只有两种情况需要转向:
- 当我们前进时遇到边界(不能超出数组长度):
x<0、x>n、y<0、y>n - 遇到自己的身体(已经填充了数字,即该位置的值不为0):
arr[x][y]!=0
知道了什时候需要转向,我们再来看看怎么转向,转向需要做什么?
//这是第一次转向的例子,此时蛇头在数组右上角
while (x < n&&arr[y][x]==0) {
arr[y][x] = value;
x++;
value++;
}
//while循环的条件不满足时,即需要转向
//首先把上一步的x++退回来
x--;
//然后把蛇头调转方向,这里是走到右上角要向下,所以是y++
y++;
//修改方向标志,可以自己随意设置
flag = '下一步的方向标志';
到这里,我们已经掌握了操纵这条皮皮蛇的所有秘诀!
下面是完整代码:
//笔试题,螺旋数组
var screwArray = function (n) {
//初始化
let value = 1;
let arr = new Array(n);
for (var i = 0; i < n; i++) {
var arr1 = new Array(n).fill(0);
arr[i] = arr1;
}
//定义方向标志:r右、l左、b下、t上
let flag = 'r';
let x = 0, y = 0
while (value <= n * n) {
switch (flag) {
case 'r':
while (x < n&&arr[y][x]==0) { //判断,符合条件才赋值
arr[y][x] = value;
x++;
value++;
}
//while终止说明需要转向,进行转向操作
x--; y++;flag = 'b';
break;
case 'b':
while (y < n&&arr[y][x]==0) {
arr[y][x] = value;
y++;
value++;
}
y--;x--; flag = 'l';
break;
case 'l':
while (x >= 0&&arr[y][x]==0) {
arr[y][x] = value;
x--;
value++;
}
x++; y--;flag = 't';
break;
case 't':
while (y >= 0&&arr[y][x]==0) {
arr[y][x] = value;
y--;
value++;
}
y++; x++;flag = 'r';
break;
}
}
console.log(arr);
}
文艺青年的结语:
人生也是一个既定过程,我们总会走到最后的终点,尽管沿途曲折,却也蜿蜒成奇丽的景色。