LeetCode 题目 118:杨辉三角

作者介绍:10年大厂数据\经营分析经验,现任字节跳动数据部门负责人。
会一些的技术:数据分析、算法、SQL、大数据相关、python,欢迎探讨交流
欢迎加入社区:码上找工作
作者专栏每日更新:
LeetCode解锁1000题: 打怪升级之旅
python数据分析可视化:企业实战案例
漫画版算法详解
python源码解读
程序员必备的数学知识与应用

题目描述

给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。在杨辉三角中,每个数是它左上方和右上方的数的和。

杨辉三角解析

在这个详解中,我们将使用 ASCII 图形来说明杨辉三角的构建过程,包括逐行添加新的行的过程。这个图解可以帮助理解每一行是如何基于前一行构建的。

杨辉三角的构建过程

初始状态
  1. 开始时,杨辉三角是空的。
第1行
  1. 添加第一行,只有一个数字 1
1
第2行
  1. 第二行有两个 1,每个都位于行的边界。
1
1 1
第3行
  1. 第三行中间的数字是上一行两个相邻数字之和(1 + 1)。
  1
 1 1
1 2 1
第4行
  1. 第四行,中间的两个数字分别是上一行相邻两数之和(1+2 和 2+1)。
    1
   1 1
  1 2 1
 1 3 3 1
第5行
  1. 第五行,中间三个数字由上行相邻数字之和得到(1+3、3+3 和 3+1)。
      1
     1 1
    1 2 1
   1 3 3 1
  1 4 6 4 1
总结过程
  • 杨辉三角的每一行都从 1 开始和结束。
  • 除了第一个和最后一个数字外,每个数字都是它正上方两个数字的和。
  • n 行(从 1 开始计数)有 n 个数字。

解题思路与算法

方法一:逐行构建
解题步骤:
  1. 初始化一个空列表 triangle 作为结果。
  2. 遍历从 0numRows-1 的每一行。
  3. 对于每一行,创建一个长度等于行号加一的新行,首尾元素设为1。
  4. 对于每一行的中间元素,按照杨辉三角的规则,由上一行的相邻两个元素求和得到。
  5. 将构建好的行添加到 triangle 中。
Python 代码示例
def generate(numRows):
    """生成杨辉三角的前numRows行"""
    triangle = []
    for row_num in range(numRows):
        row = [None for _ in range(row_num + 1)]
        row[0], row[-1] = 1, 1  # 第一个和最后一个元素始终为1
        for j in range(1, len(row) - 1):
            row[j] = triangle[row_num - 1][j - 1] + triangle[row_num - 1][j]
        triangle.append(row)
    return triangle
方法二:一行代码解
解题步骤:
  1. 使用列表推导式和递推公式直接生成杨辉三角的每一行。
  2. 利用 Python 的生成器语法简化代码实现。
Python 代码示例
def generate(numRows):
    """一行代码生成杨辉三角"""
    return [[1 if j == 0 or j == i else triangle[i-1][j-1] + triangle[i-1][j] for j in range(i+1)] for i in range(numRows)]
方法三:动态规划
解题步骤:
  1. 初始化一个空列表 triangle
  2. 从第一行到第 numRows 行,利用动态规划的思想,每一行基于前一行生成。
  3. 同样地,每行的首尾元素为1,其他元素由上一行的两个相邻元素相加得到。
  4. 每生成一行即存入 triangle
Python 代码示例
def generate(numRows):
    triangle = []
    for row_num in range(numRows):
        row = [1] * (row_num + 1)  # 每行元素初始化为1
        for j in range(1, row_num):
            row[j] = triangle[-1][j - 1] + triangle[-1][j]
        triangle.append(row)
    return triangle
方法四:使用递归
解题步骤:
  1. 定义递归函数,如果请求行数为1,返回只包含一行的杨辉三角。
  2. 否则,递归调用自身生成前 numRows - 1 行,然后基于最后一行计算新的一行,并添加到结果中。
Python 代码示例
def generate(numRows):
    if numRows == 1:
        return [[1]]
    else:
        result = generate(numRows - 1)
        last_row = result[-1]
        new_row = [1]
        for i in range(1, len(last_row)):
            new_row.append(last_row[i - 1] + last_row[i])
        new_row.append(1)
        result.append(new_row)
        return result
方法五:迭代改进版
解题步骤:
  1. 初始化一个包含第一行的列表。
  2. 迭代从第二行开始,每一行都通过上一行来计算。
  3. 使用临时列表存储当前行,计算完成后加入最终结果。
Python 代码示例
def generate(numRows):
    triangle = [[1]]
    for row_number in range(1, numRows):
        prev_row = triangle[-1]
        current_row = [1]
        for j in range(1, row_number):
            current_row.append(prev_row[j-1] + prev_row[j])
        current_row.append(1)
        triangle.append(current_row)
    return triangle

算法分析

  • 时间复杂度
    • 所有方法的时间复杂度基本为 (O(n^2)),其中 (n) 是行数。每行的计算成本大约与行号成正比。
  • 空间复杂度
    • 方法一、三、四和五:(O(n^2)),需要存储整个三角形。
    • 方法二:同样是 (O(n^2)),但因为使用了列表推导,可能有额外的内存开销。

不同算法的优劣势对比

  • 逐行构建(方法一)直观易理解,适合大多数初学者。
  • 一行代码解(方法二)代码简洁,但可能在理解和调试时较为复杂。
  • 动态规划(方法三)标准且易于理解,展示了动态规划思想的典型应用。
  • 使用递归(方法四)代码简洁,但对于大的行数可能导致调用栈溢出。
  • 迭代改进版(方法五)提供了介于方法一和方法三之间的解决方案,保持了代码的清晰性和执行的高效性。

应用示例

杨辉三角可以用于计算组合数学中的二项式系数,这在概率论、统计学和算法设计中非常有用。例如,它可以用来计算多项式展开的系数,或者在计算概率时快速找到相关的系数。在图形设计中,杨辉三角也被用于计算贝塞尔曲线等复杂图形的点。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据分析螺丝钉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值