leetcode杨辉三角

给定一个非负整数 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')]

在上面的示例中,ab 是两个长度相同的列表。使用 zip() 函数将它们打包起来,得到一个可迭代对象 c,其中每个元素都是一个元组,包含 ab 中对应位置上的值。

回到原题目的代码 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=0j=n-1 的位置时,需要使用上一行中不存在的值,此时我们可以将这些位置的值设置为 0。因此,我们需要构造两个长度等于 n 的列表 [0]+res[-1]res[-1]+[0],分别表示上一行的左侧和右侧各添加了一个 0

例如,当计算第三行时,假设上一行为 [1, 2, 1],则下一行的计算过程为:

  1. 在前后各添加一个 0 得到两个新列表:[0, 1, 2, 1] 和 [1, 2, 1, 0]
  2. 使用 zip() 函数将它们打包成一个元组列表:[(0, 1), (1, 2), (2, 1), (1, 0)]
  3. 使用列表推导式将相邻的元素相加得到该行的全部元素:[1, 3, 3, 1]

因此,zip([0]+res[-1], res[-1]+[0]) 这一行代码的作用就是构造具有左右两侧补零特性的两个列表,并将它们按元素两两组合。这样得到的元组列表就可以用来计算某一层中每个位置上的元素了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值