Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说杨辉三角python代码_python分类算法,希望能够帮助你!!!。
关注微信公众号“酸痛鱼”,获得更多最新最全的文章。
本文中所涉及的代码,在未特殊声明的情况下,都是基于Python3程序设计语言编写的。
建议您在PC浏览器中阅读本文,以获得更好的阅读体验。
如果您未掌握知识提要中的内容,建议您先掌握这些内容之后再阅读本文。如果您看不懂本期的内容,建议您先阅读往期文章。
知识提要
1、range、lambda、reduce
2、二项式系数、组合数、杨辉三角
3、列表过滤语法
0
问题描述
杨辉三角,是二项式系数在三角形中的一种几何排列。给定一个非负索引n,返回杨辉三角的第n行。
例如:
输入:0
返回:[1]
输入:1
返回:[1, 1]
输入:2
返回:[1, 2, 1]
杨辉三解又叫Pascal’s Triangle,为了表述方便,在下文中,我们将用P(n)来代码杨辉三解的第n行。
1
问题分析
二项式系数,是二项(x+y)^n展开后各项的系数,第r列的值为C(n, r)。
杨辉三角是二项系数的几何排列,其相临两个行存在递推关系,如动图所示(图片来源于网络,若侵权,请通知删除),以及组合数的性质,我们可以推算出如下递推规律:
C(n, 0) = 1
C(n, n) = 1
C(n, r) = C(n - 1, r – 1) + C(n – 1, r) # n>1且r>0
所以,我们解决此题目的方式有两种,一种是公式法,一种是递推法。我们将首先介绍公式法,然后介绍递推法。本文的重点是介绍递推法,我们将一步步地简化递推法的空间复杂度。
2
公式法
根据二项式展开式的规律,我们知道:
P(n) = [C(n, 0), C(n, 1), …, C(n, n)]
所以我们只需要实现一个求组合数的函数即可以解决问题。
from functools import reduce
# 获取组合数C(n, m)
def combination(n, m):
if n <= m or m <= 0: return 1
if m > n / 2:
m = n - m
func = lambda a, b: a * b
val1 = reduce(func, range(m + 1, n + 1))
val2 = reduce(func, range(1, n - m + 1))
return val1 // val2
# 获取杨辉三角第n行
def GetTriangleRow(n):
return [combination(n, i) for i in range(n + 1)]
3
递推法
我们可以根据递推规律,构建杨辉三角,返回杨辉三角的最后一行即可。
# 获取杨辉三角第n行
def GetTriangleRow(n):
matrix = [[1] * (col + 1) for col in range(0, n + 1)]
for row in range(2, n + 1):
for col in range(1, row):
matrix[row][col] = matrix[row - 1][col - 1] + matrix[row - 1][col]
return matrix[n]
4
空间复杂度为O(n)的递推法
在第3节中,构建杨辉三角,需要存储大量额外临时空间matrix,matrix的元素数量为n(n+1)/2,所以空间复杂度为O(n^2)。
实际上,根据递推公式,我们只需要不停地存储P(n-1)和P(n)的结果即可,用此方法,空间复杂度可以降低为O(n)。虽然我们用到的空间是2n,但O(2n)也是O(n)。
def GetTriangleRow(n):
size = n + 1
result = [1] * size
for cols in range(3, size + 1):
cur_row = [1] * cols
for j in range(1, cols - 1):
cur_row[j] = result[j - 1] + result[j]
result = cur_row
return res
5
进一步减少递推法的空间复杂度
在第4节中,我们已经达到现了O(2n)的空间复杂度的效果。但如果我们非得实现真正意义上的O(n)也是可以做到的。
组合数公式有如下的规律:
C(n, r) = C(n, n – r)
根据这个规律,我们可以一开始便初始化P(n)的空间。在每一次迭代中,用P(i-1)的后一半的数值来推算出P(i)前一半的数值,并将P(i)前一半的结果存储在原来存储P(i-1)前一半数值的地方。最后用P(i)前一半得到P(i)后一半的结果。
由于P(i-1)中间项的值有可能会在推算P(i)的过程中被覆盖,所以我们需要首先单独推算并存储P(i)的中间一项。请关注代码中的mid_val变量。
def GetTriangleRow(n):
size = n + 1
result = [1] * size
for cols in range(2, size):
m = cols // 2
mid_val = result[m - 1] + result[m]
for j in range(1, m):
result[j] = result[cols - j] + result[cols - j - 1]
result[m] = mid_val
for j in range(m + 1, cols):
result[j] = result[cols - j]
return result● 扫码关注我嗄嘎嘎
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。