利用列表巧妙打印杨辉三角

Python中的列表(list)

  在python中,列表的重要性不亚于C语言中的数组,用好python中的列表对提升编程能力以及提高程序效率很有帮助。下面就介绍几种用列表实现杨辉三角的方法。

方法一:二维列表首尾加1

  首先将特殊的前两行[1],[1,1]列出,然后根据杨辉三角首尾都是1以及当前行的除首尾项外的其他项均为上一行的相邻两项之和的性质,堆叠出杨辉三角的下一行。简言之就是将整个杨辉三角看作是一个大列表,每一行就是这个大列表中的元素,大列表中的元素要根据上一个元素中的相邻元素相加得到。

n=int(input('num:'))
triangle = [[1],[1,1]] #列出最开始的两特殊项
print([1])
print([1,1])
for i in range(2,n): #计数,产生大列表的新元素(杨辉三角的新行)
    newline = [1] #新行的首项
    pre = triangle[i-1] #将杨辉三角列表中的当前最后一个元素抽出,为计算下一元素做准备
    for j in range(i-1): #从0开始计数
        val = pre[j]+pre[j+1] #将抽出的元素从当前项开始累加
        newline.append(val) #累加的值循环堆入下一行
    newline.append(1) #最后堆入最后一项1
    triangle.append(newline) #将新生成的元素再堆入杨辉三角列表
    print(newline)
#print(triangle)

方法二:一维列表首尾加0

n = int(input('num:'))
lst = [1]
print(lst)
lst.insert(0,0) #在索引0的位置插入元素0
lst.append(0) #在最后插入元素0
for i in range(1,n):
    new = []
    for j in range(i+1):
        new.append(lst[j]+lst[j+1]) #j从0开始,将前一行的元素循环累加的结果堆入new
    print(new)
    lst = new #将结果重新给lst准备下一次循环打印下一行
    lst.insert(0, 0)
    lst.append(0)

  上面的方法会使用列表的insert,而insert的时间复杂度为O(n),效率很低,下面尝试将insert去除。

方法三:巧用负索引消除insert:

  在python列表中,既有正索引也有负索引,在上例中用insert插入的每行第一个1可以用索引0与索引-1相加得到,这样就省去了insert这一步,提升了效率。

n = int(input('num:'))
lst = [1]
print(lst)
#lst.insert(0,0)
lst.append(0)
for i in range(1,n):
    new = []
    for j in range(i+1):
        new.append(lst[j-1]+lst[j]) #这里是关键
    print(new)
    lst = new.copy()
    #lst.insert(0, 0)
    lst.append(0)
    new.clear() #清空new

方法四:二维列表对折:

  在这个对折算法中,需要事先就将需要的列表内存空间全部准备好,也就是说如果我们要打印6行的杨辉三角,就在计算各行各元素之前就将整个6行所需要的杨辉三角内存空间整理出来,而不是在循环体中一边计算一边增加内存空间。这样效率就会有很大的提升了。

  另外,在这个对折的算法中要考虑到中心点的情况,也就是说每一行的行号与该行的元素之间的关系,何时对折,何时不对折。

triangle = []
n = int(input('num:'))
for i in range(n): #用循环将整个列表需要的内存空间事先整理出来
    row = [1]*(i+1)
    triangle.append(row) #将内存地址传给triangle
    for j in range(1,i//2+1): #每一行最多需要算几次,因为是对折,所以最多只要算行数的一半,j从1开始,所以后面要加1
        val = triangle[i-1][j-1]+triangle[i-1][j] #上一行的第j-1个元素加上上一行的第j个元素,并赋值给val
        row[j]=val #再将val填入当前行的第j个元素
        if i !=2*j: #这里是关键,可以理解为,只要不满足i==2*j这个条件就将值对折
            row[-j-1]=val
    print(triangle[i]) #打印二维列表的第i个元素就是打印当前行

方法五:单列表对折:

n = int(input('num:'))
#n = 6
lst = [1]
print(lst)
#lst.insert(0,0)
#lst.append(0)
for i in range(1,n):
    new = [1]*(i+1)
    for j in range(1,i//2+1):
        new[j]=lst[j-1]+lst[j]
        if i!=2*j:
            new[-j-1] = lst[j-1]+lst[j]
    print(new)
    lst = new.copy()
    #lst.insert(0, 0)
    #lst.append(0)
    new.clear()

 

 

posted @ 2019-01-04 13:37  readygood  阅读(953)  评论(0编辑  收藏  举报