给定一个非负整数 numRows
,生成「杨辉三角」的前 numRows
行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
示例 1:
输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
示例 2:
输入: numRows = 1
输出: [[1]]
提示:
1 <= numRows <= 30
法一、
class Solution(object):
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
"""
tr=[]
i=0
#i为层数,j为列数
while i<numRows:
j=0
ceng=[]
while j<=i:
if j==0 or j==i:
ceng.append(1)
else:
ceng.append(tr[i-1][j-1]+tr[i-1][j])
j+=1
tr.append(ceng)
i+=1
return tr
双层循环,随后在内层循环设计一个列表,若为第一列或最后一个,值为1,其他的利用分层解决,通俗易懂。
chatgpt生成代码解释如下:
class Solution(object):
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
"""
# tr 列表用于保存杨辉三角形各行的元素,首先初始化为空列表。
tr = []
# i 表示当前正在生成的行数,从第一层(即 i=0)开始逐层生成直至达到 numRows 层数要求。
i = 0
while i < numRows:
j = 0
# ceng 列表用于保存当前层中的各个元素值,每一次内部循环会向其添加一个新的元素。
ceng = []
# 在生成每一层时,使用内部循环构造该层中的每个元素。
# 对于每一行,根据杨辉三角形的定义可知,该行中共有 i+1 个元素,这里对 j 进行遍历以取得该行中的每个元素。
while j <= i:
# 如果当前元素是该行的第一列或最后一列,那么它的值为 1。
if j == 0 or j == i:
ceng.append(1)
# 如果当前元素不是第一列或最后一列,那么它的值等于上一行对应位置处的两个元素值之和。
else:
ceng.append(tr[i-1][j-1] + tr[i-1][j])
# 将 j 的值加 1,处理下一个元素。
j += 1
# 将当前层(即 ceng 列表)添加到 tr 中保存。
tr.append(ceng)
# 将 i 的值加 1,进入下一层循环,继续生成下一行的杨辉三角形元素。
i += 1
# 最后返回生成的二维列表 tr。
return tr
法二、
* 1
* 1 1
* 1 2 1
* 1 3 3 1
* 1 4 6 4 1
* 规律:当前行等于上一行错位相加
* 如第3行通过规律可以通过如下错位相加而得
* 1 2 1 0
* 0 1 2 1
* ------------------
* 1 3 3 1
*
看题解有人用的,很巧妙
class Solution:
def generate(self, numRows: int) -> List[List[int]]:
# 判断 numRows 是否为零,如果为零,则返回一个空列表。
if numRows == 0: return []
# 创建一个初始列表 [[1]]
res = [[1]]
# 循环计算从第二行到第 numRows 行每个位置上的元素。
while len(res) < numRows:
# 构造当前需要计算的这一行的列表 newRow。
# 在计算某一行的元素时,将该行的左侧和右侧各补一个 0 组成两个长度等于当前行元素个数加 1 的新列表,
# 然后使用 zip 函数打包成一个元组列表,在利用列表推导式将相邻的元素相加得到该行的全部元素。
newRow = [a+b for a, b in zip([0]+res[-1], res[-1]+[0])]
# 将计算得到的 newRow 添加到结果列表中。
res.append(newRow)
# 循环直至计算完所有行,最后返回结果列表 res。
return res
zip([0]+res[-1], res[-1]+[0])]怎么解释???
zip()
函数可以将多个列表按元素依次打包成元组,然后返回由这些元组组成的可迭代对象。例如:
a = [1, 2, 3]
b = ['a', 'b', 'c']
c = zip(a, b)
print(list(c)) # [(1, 'a'), (2, 'b'), (3, 'c')]
在上面的示例中,a
和 b
是两个长度相同的列表。使用 zip()
函数将它们打包起来,得到一个可迭代对象 c
,其中每个元素都是一个元组,包含 a
和 b
中对应位置上的值。
回到原题目的代码 zip([0]+res[-1], res[-1]+[0])
。首先定义了一个长度为 n
的列表 res
,表示杨辉三角形前 n
行的元素值。我们需要计算第 i+1
行(即列表下标为 i
),也就是通过第 i
行推导出的结果。为了计算第 i+1
行的元素值,只需要使用第 i
行的元素值即可。所以,我们可以通过 res[-1]
来取得第 i
行的值。
具体来说,列表 res
初始只有一个元素:[[1]]。当要计算第二行时,首先假设该行为 [1, 2, 1]
,然后根据杨辉三角形的定义,第 i+1
行中的第 j
个元素应该等于第 i
行中的 res[i][j-1] + res[i][j]
。在计算第 j=0
和 j=n-1
的位置时,需要使用上一行中不存在的值,此时我们可以将这些位置的值设置为 0
。因此,我们需要构造两个长度等于 n
的列表 [0]+res[-1]
和 res[-1]+[0]
,分别表示上一行的左侧和右侧各添加了一个 0
。
例如,当计算第三行时,假设上一行为 [1, 2, 1]
,则下一行的计算过程为:
- 在前后各添加一个
0
得到两个新列表:[0, 1, 2, 1]
和[1, 2, 1, 0]
- 使用
zip()
函数将它们打包成一个元组列表:[(0, 1), (1, 2), (2, 1), (1, 0)]
- 使用列表推导式将相邻的元素相加得到该行的全部元素:
[1, 3, 3, 1]
因此,zip([0]+res[-1], res[-1]+[0])
这一行代码的作用就是构造具有左右两侧补零特性的两个列表,并将它们按元素两两组合。这样得到的元组列表就可以用来计算某一层中每个位置上的元素了。