问题描述
小U面临一个有趣的任务:在一个 n×n 的方阵中填入 1 到 n×n 这些数字,并要求按照蛇形顺序从右上角开始,沿着方阵的边界顺时针进行填充。蛇形填充的特殊排列方式使得每一层数字呈现出波浪形的排列方式。
例如,当 n=4 时,方阵应如下所示:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
题目分析
本题要求按照规则填充一个二维数组
由题意可得,规则:沿着方阵的边界顺时针进行填充
更进一步分析可得以下规律:
1、当数字在右边界时,数字往下递增
2、当数字在下边界时,数字往左递增
3、当数字在左边界时,数字往上递增
4、当数字在上边界时,数字往右递增
代码实现
当n=1时,需要创造一个[[1]]的数组
if n==1:
return [[1]]
当n>1时,我们先创造1个n*n的二维数组
else:
ans=[[0]*n for i in range(n)] #创造二维数组
left=0;right=n-1;up=0;down=n-1 #设立边界
i=0;j=n-1 #下标
n=1 #递增的数
flag=0 #设置一个标志,用于后续判断
ans[i][j]=n #右上角的元素设为1
i+=1;n+=1
接着用代码实现规则
while(ans[i][j]==0):
ans[i][j]=n
if j==left and i==down:
right-=1
elif i==up and j==left:
down-=1
elif j==right and i==up:
left+=1
elif i==down and j==right and flag==1:
up+=1
if j==right and i!=down:
i+=1
n+=1
elif j==left and i!=up:
i-=1
n+=1
elif i==down and j!=left:
j-=1
n+=1
elif i==up and j!=right:
j+=1
n+=1
flag=1
while(ans[i][j]==0)这是判断循环是否进行的条件,当此时的元素为0(即还没有赋值),我们就要对其赋值(ans[i][j]=n)
后面一大段我们分成两个小段来看
1、
观察可以发现,我们的边界是要不断更新的,例如:当n-1列排满时,右边界应该变为n-2
为了实现这一目的,我一开始的想法是:
错误代码
if j==right and i==down:
right-=1
elif j==left and i==up:
left+=1
elif i == down and j == left:
down-=1
elif i == up and j == right:
up+=1
我打算在下标到达右下角时就更新右边界,结果发现此时j-=1,right-=1,导致(j==right and i==down)这一判断条件不断实现,最终right=-1。
所以我更改为了:
if j==left and i==down:
right-=1
elif i==up and j==left:
down-=1
elif j==right and i==up:
left+=1
elif i==down and j==right and flag==1:
up+=1
新代码在下标到达左下角时才更新边界,这样就不会出现上述的问题。
但此时又有了一个新问题,因为下标会先到达右下角才到达左下角,所以上边界会比有边界先更新,这很明显是错误的。
所以我加入了一个flag,当我们的下标已经经过右边界、下边界、左边界来到上边界后,才开始更新上边界。
2、
if j==right and i!=down:
i+=1
n+=1
elif j==left and i!=up:
i-=1
n+=1
elif i==down and j!=left:
j-=1
n+=1
elif i==up and j!=right:
j+=1
n+=1
flag=1 #说明下标已经经过右边界、下边界、左边界来到上边界
当j==right and i!=down(即到达右边界且不是右下角时),我们的i+=1(即向下) n+=1(即递增)
同理其他也是按照规则,最终得出想要的蛇形数列。