Python项目实战之绕圈圈面试题—递归应用

网上流传的Python学习教程有《项目实战之绕圈圈面试题》这一节,对原文中的代码重新写了一下。

SIZE = 6
array = [[0] * SIZE] 
while len(array)<SIZE: 
    array += [[0] * SIZE] 
    # 创建一个长度SIZE * SIZE的二维列表 

def NumCircle(first,be,en):    #第一个函数
    if(en>be):
        for i in range(be,en):
            array[i][be]=first    #左侧列元素,行号i列号be
            first+=1
        for i in range(be,en):
            array[en][i]=first    #下方行元素,行号en列号i
            first+=1
        for i in range(en,be,-1):
            array[i][en]=first    #右侧列元素,行号i列号en
            first+=1
        for i in range(en,be,-1):
            array[be][i]=first    #上方行元素,行号be列号i
            first+=1
    else:
        array[be][be]=first
    if en-be<=1:    #2×2或一个元素是递归退出条件
        return
    else:
        be+=1
        en-=1
        NumCircle(first,be,en)

def NumRound(first,be,en):    #第二个函数,功能完全等同于第一个
    incList=list(zip([1,0,-1,0],[0,1,0,-1]))    
    #组成列表(1, 0), (0, 1), (-1, 0), (0, -1),表示在四个方向上二维列表的行列下标增加值,
    #1,0表示行加1,列不变
    array[be][be]=first
    if en>be:
        j=k=be      #j-行号,k-列号,从左上角出发
        i=0
        while not (j==be and k==be+1):       #表示起始元素右边相邻的元素
            if [j,k]==[be,en] or [j,k]==[en,en] or [j,k]==[en,be] :
                #分别到达左下、右下、右上三个顶点
                i+=1
                #i=0,1,2,3,表示左下右上四个方向
            j,k=map(lambda x,y:x+y,[j,k],incList[i])
            #计算出下一个元素的行号列号
            first+=1
            array[j][k]=first
    if en-be<2:
        return    #2×2或一个元素是递归退出条件
    else:
        first,be,en=map(lambda x,y:x+y,[first,be,en],[1,1,-1])
        NumRound(first,be,en)

def printtarr(func):    #打印函数
    func(1,0,SIZE-1)
    for x in array : 
        for y in x : 
            print('%02d ' % y, end = "")
        print("")

printtarr(NumCircle)
printtarr(NumRound)    

原文摘抄:

下面是来自某知名公司的一道“面试题”:给定 4,应该输出如下形式的数据:

01 12 11 10

02 13 16 09

03 14 15 08

04 05 06 07

给定 5,应该输出如下形式的数据:

01 16 15 14 13

02 17 24 23 12

03 18 25 22 11

04 19 20 21 10

05 06 07 08 09

仔细观察上面的试题,不难发现程序就是“绕圈圈”填入整数,如图 1 所示:

图 1 填数规则

掌握上面的规律之后,我们打算使用列表嵌套列表(相当于二维列表)的方式来存储这些整数,将数值存入嵌套列表时需要遵守这种“绕圈圈”的规则,然后再以二维方式将这个嵌套列表打印出来。

找到图中 ①、②、③ 号转弯线之后,可以发现如下规则: 1、 位于 ① 号转弯线的行索引与列索引总和为 n - 1(即给定整数值减 1)。 2、 位于 ② 号转弯线的行索引与列索引相等。3、 位于 ③ 号转弯线的行索引等于列索引减 1。

修改的算法:

定义一个函数,这个函数能够在方阵的周围单元填入数列:NumRound(first,be,en)。first是填入的第一个数,be是左上角索引,en是右下角索引。

下一步first+1,be+1,en-1,如下图在圈内空白处填充第二层。此过程由递归调用自身实现,直到填充完中间空格(阶数为偶数如下图的中心4个空格。奇数就只有一个空格),递归跳出。

SIZE=6

SIZE=7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值