蛇形填充n阶方阵

98 阅读3分钟

问题描述

小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(即递增)

同理其他也是按照规则,最终得出想要的蛇形数列。