[特殊字符] 第72课:杨辉三角

news2026/4/9 6:56:24
想系统提升编程能力、查看更完整的学习路线欢迎访问 AI Compasshttps://github.com/tingaicompass/AI-Compass仓库持续更新刷题题解、Python 基础和 AI 实战内容适合想高效进阶的你。 第72课:杨辉三角模块:动态规划 |难度:Easy ⭐LeetCode 链接:https://leetcode.cn/problems/pascals-triangle/前置知识:无预计学习时间:20分钟 题目描述给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。在杨辉三角中,每个数是它左上方和右上方的数的和。示例:输入:numRows 5 输出:[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 可视化: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1约束条件:1 numRows 30需要返回二维数组,不是打印 边界用例(面试必考)用例类型输入期望输出考察点最小输入numRows1[[1]]只有顶点小规模numRows2[[1],[1,1]]第二行有两个1中等规模numRows5[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]验证递推逻辑大规模numRows3030行三角形性能边界 思路引导生活化比喻想象你在搭积木金字塔,从顶端的1个积木开始,每一层的积木数量都比上一层多1。关键规则是:每个积木上的数字 它左上方的数字 右上方的数字。笨办法:用数学公式计算每个位置的值(组合数公式 C(n,k)),需要计算阶乘,容易溢出且效率不高。聪明办法:观察规律——每一行的第一个和最后一个数字都是1,中间的数字都是上一行相邻两个数字之和。所以我们可以逐行生成:先在两端放1,中间的数字从上一行推导出来。这就是二维动态规划的入门思想。关键洞察当前行的每个数字(除了首尾的1) 上一行相邻两个数字之和 解题思维链这一节模拟你在面试中从零开始思考的过程。Step 1:理解题目 → 锁定输入输出输入:一个正整数 numRows,表示要生成的行数输出:一个二维列表,包含杨辉三角的前 numRows 行限制:每行第一个和最后一个数字是1,中间数字由上一行推导Step 2:先想笨办法(数学公式法)杨辉三角第n行第k个数字的数学公式是组合数 C(n, k) n! / (k! * (n-k)!),可以直接计算。时间复杂度:O(numRows²) — 需要计算每个位置的组合数瓶颈在哪:计算阶乘容易溢出,且需要重复计算,效率不高Step 3:瓶颈分析 → 优化方向观察杨辉三角的规律:每一行的数字都可以从上一行推导出来,不需要每次重新计算阶乘。核心问题:数学公式计算复杂,且没有利用前一行的结果优化思路:能不能基于前一行直接生成当前行?→用逐行递推Step 4:选择武器选用:动态规划(二维DP)理由:当前行依赖上一行,具有明显的递推关系,适合DP自底向上生成模式识别提示:当题目出现第n行依赖第n-1行、“逐层构建时,优先考虑动态规划” 解法一:逐行递推(标准DP)思路从第一行开始,逐行生成杨辉三角。每一行的首尾都是1,中间的数字通过访问上一行相邻两个位置相加得到。图解过程生成过程(以 numRows5 为例): 第1行: [1] ↓ 第2行: [1, 1] ↓ ↓ ↓ 第3行: [1, 2, 1] ↗ ↖ ↗ ↖ 112 ↓ 第4行: [1, 3, 3, 1] ↗ ↖ ↗ ↖ ↗ ↖ 123 213 ↓ 第5行: [1, 4, 6, 4, 1] ↗ ↖ ↗ ↖ ↗ ↖ ↗ ↖ 134 336 314 规律总结: row[j] prev_row[j-1] prev_row[j] (1 j len(row)-1)Python代码fromtypingimportListdefgenerate_pascal_triangle(numRows:int)-List[List[int]]: 解法一:逐行递推(标准DP) 思路:基于上一行生成当前行,首尾为1,中间为上一行相邻两数之和 result[]foriinrange(numRows):# 创建当前行,长度为 i1,初始化为1row[1]*(i1)# 计算中间元素(第一个和最后一个保持为1)ifi2:# 从第3行开始才有中间元素prev_rowresult[i-1]# 上一行forjinrange(1,i):# j 从 1 到 i-1row[j]prev_row[j-1]prev_row[j]result.append(row)returnresult# ✅ 测试print(generate_pascal_triangle(1))# 期望输出: [[1]]print(generate_pascal_triangle(3))# 期望输出: [[1],[1,1],[1,2,1]]print(generate_pascal_triangle(5))# 期望输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]复杂度分析时间复杂度(numRows²) — 总共生成 123…numRows numRows*(numRows1)/2 个数字具体地说:如果 numRows30,大约需要生成 30*31/2 465 个数字空间复杂度(numRows²) — 存储整个三角形的所有数字优缺点✅ 代码清晰,易于理解✅ 利用递推关系,避免重复计算⚠️ 空间复杂度无法优化(题目要求返回整个三角形) 解法二:优化写法(代码简化,最优解)优化思路观察解法一,我们可以在生成每一行时边遍历边计算,不需要单独判断i 2。而且可以用更简洁的方式访问上一行。关键想法:简化代码逻辑,让循环更统一图解过程优化思路: 对于每一行,先创建全是1的数组,然后只修改中间部分 生成第4行 [1, 3, 3, 1] 的过程: 1. 创建: row [1, 1, 1, 1] (长度为4) 2. 修改: row[1] prev_row[0] prev_row[1] 1 2 3 row[2] prev_row[1] prev_row[2] 2 1 3 3. 保持: row[0] 1, row[3] 1 不变Python代码defgenerate_optimized(numRows:int)-List[List[int]]: 解法二:优化写法 — 最优解 思路:与解法一相同,但代码更简洁 result[]foriinrange(numRows):# 当前行初始化为全1row[1]*(i1)# 更新中间元素forjinrange(1,i):row[j]result[i-1][j-1]result[i-1][j]result.append(row)returnresult# ✅ 测试print(generate_optimized(5))# 期望输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]复杂度分析时间复杂度(numRows²) — 与解法一相同空间复杂度(numRows²) — 与解法一相同为什么是最优解:时间复杂度已经最优(必须生成所有数字)空间复杂度受题目限制(必须返回整个三角形)代码更简洁,循环逻辑更清晰 Pythonic 写法利用 Python 的列表推导式和 zip 函数,可以写出非常简洁的版本:# 方法一:列表推导式defgenerate_pythonic(numRows:int)-List[List[int]]:result[[1]]for_inrange(numRows-1):prevresult[-1]# 构造当前行: [1] 中间部分 [1]row[1][prev[i]prev[i1]foriinrange(len(prev)-1)][1]result.append(row)returnresultifnumRows0else[]# 方法二:使用 zip 妙用defgenerate_zip(numRows:int)-List[List[int]]:result[[1]]for_inrange(numRows-1):prevresult[-1]# zip([1,2,1], [0,1,2]) [(1,0), (2,1), (1,2)]# 但我们需要 [12, 21] [3, 3]# 技巧: zip(prev, prev[1:]) [(1,2), (2,1)]row[1][abfora,binzip(prev,prev[1:])][1]result.append(row)returnresultifnumRows0else[]zip(prev, prev[1:])的巧妙之处:prev [1, 2, 1]prev[1:] [2, 1]zip(prev, prev[1:]) [(1,2), (2,1)]— 恰好是相邻两个数的配对![ab for a,b in zip(...)][12, 21][3, 3]⚠️面试建议:先写清晰版本展示思路,再提 Pythonic 写法展示语言功底。面试官更看重你的思考过程,而非代码行数。 解法对比维度解法一:标准递推 解法二:优化写法(最优)时间复杂度O(numRows²)O(numRows²)← 理论最优空间复杂度O(numRows²)O(numRows²)← 题目要求代码难度简单简单面试推荐⭐⭐⭐⭐⭐← 首选适用场景清晰展示逻辑代码简洁,面试首选为什么解法二是最优解:时间复杂度 O(numRows²) 已经是理论最优(必须生成所有数字,无法更快)空间复杂度受题目限制(必须返回整个三角形,无法更省)代码更简洁,循环逻辑更统一,面试中更容易写对面试建议:先用1分钟画图展示杨辉三角的递推规律:“每个数 左上 右上”立即写出最优解的代码,强调首尾为1,中间从上一行推导手动模拟生成前3行的过程,展示对递推的理解测试边界用例(numRows1),验证代码正确性如果时间允许,展示 Pythonic 写法(zip技巧),加分项 面试现场模拟面试中的完整对话流程,帮你练习边想边说。面试官:请你生成杨辉三角的前n行。你:(审题30秒,画出示例)好的,杨辉三角的规律是:每一行的第一个和最后一个数字都是1,中间的数字是上一行相邻两个数字之和。比如第4行的3 上一行的12。我的思路是逐行生成:从第1行 [1] 开始,每次基于上一行生成当前行。具体步骤是:创建长度为 i1 的数组,全部初始化为1遍历中间位置(从1到i-1),计算row[j] prev_row[j-1] prev_row[j]将当前行加入结果时间复杂度 O(n²),空间复杂度 O(n²),都是最优的。面试官:很好,请写代码。你:(边写边说)defgenerate(numRows):result[]foriinrange(numRows):row[1]*(i1)# 先全部填1forjinrange(1,i):# 更新中间元素row[j]result[i-1][j-1]result[i-1][j]result.append(row)returnresult面试官:测试一下?你:用 numRows3 走一遍:i0: row[1], result[[1]]i1: row[1,1], result[[1],[1,1]]i2: row[1,1,1], 更新 row[1]result[1][0]result[1][1]112, 得到 [1,2,1], result[[1],[1,1],[1,2,1]]结果正确。边界情况 numRows1 返回 [[1]],也正确。高频追问追问应答策略“能不能只返回第n行,而不生成整个三角形?”“可以!只需要维护当前行和上一行,空间优化到 O(n)。核心思想是用两个数组交替更新,或者用一个数组从后往前更新(避免覆盖)。”“如何计算杨辉三角第n行第k个数?”“可以用组合数公式 C(n,k),或者用递推关系从第1行一直算到第n行。如果只要一个数,用公式更快。”“杨辉三角有什么应用?”“杨辉三角在数学中就是组合数表,应用很广:二项式展开系数、概率计算(如抛硬币)、组合优化问题等。”“能否用递归实现?”“可以,递归计算 C(n,k) C(n-1,k-1) C(n-1,k),但需要记忆化避免重复计算,本质上和迭代DP相同。” 知识点总结Python技巧卡片 # 技巧1:列表推导式 — 简洁生成列表row[1][prev[i]prev[i1]foriinrange(len(prev)-1)][1]# 技巧2:zip 妙用 — 生成相邻元素配对# zip([1,2,1], [2,1]) [(1,2), (2,1)]row[1][abfora,binzip(prev,prev[1:])][1]# 技巧3:列表切片 — prev[1:] 从第2个元素到末尾prev[1,2,1]prev[1:][2,1]# 去掉第一个元素 底层原理(选读)为什么杨辉三角和组合数有关?杨辉三角第n行第k个数字(从0开始计数)恰好是组合数 C(n, k) n! / (k! * (n-k)!)。组合数的递推关系是:C(n, k) C(n-1, k-1) C(n-1, k)这恰好对应杨辉三角的左上右上规则!应用举例:二项式展开:(ab)^n 的系数就是杨辉三角第n行(ab)² 1·a² 2·ab 1·b² → 系数 [1, 2, 1](ab)³ 1·a³ 3·a²b 3·ab² 1·b³ → 系数 [1, 3, 3, 1]概率计算:抛3次硬币,恰好2次正面的概率 C(3,2)/2³ 3/8算法模式卡片 模式名称:二维DP(逐行递推)适用条件:当前行依赖上一行,需要生成多行结果识别关键词:“杨辉三角”、“帕斯卡三角”、“逐行生成”、“上一行推导当前行”模板代码:defgenerate_rows(n):result[]foriinrange(n):# 初始化当前行row[initial_value]*(i1)# 基于上一行更新当前行ifi0:prev_rowresult[i-1]forjinrange(1,i):row[j]transition_function(prev_row,j)result.append(row)returnresult易错点 ⚠️索引越界:访问result[i - 1]时忘记判断 i 0,导致访问 result[-1] 拿到错误的最后一行正确做法:确保 i 1 时才访问上一行,或者从 i1 开始循环边界处理错误:忘记处理 numRows0 或 numRows1 的情况正确做法:在函数开头判断if numRows 0: return []修改了首尾元素:循环范围写成range(0, i1)导致覆盖了首尾的1正确做法:循环范围应该是range(1, i),只修改中间元素️ 工程实战(选读)这个算法思想在真实项目中的应用,让你知道学了有什么用。场景1:数据分析 — 计算多项式展开系数,用于信号处理中的滤波器设计(如二项式滤波器)场景2:概率计算 — 在金融风控中计算多次独立事件的组合概率(如贷款违约概率)场景3:图形渲染 — 贝塞尔曲线的系数计算使用杨辉三角中的组合数️ 举一反三完成本课后,试试这些同类题目来巩固知识:题目难度相关知识点提示LeetCode 119. 杨辉三角 IIEasyDP空间优化只返回第n行,可以用O(n)空间的滚动数组LeetCode 120. 三角形最小路径和MediumDP递推类似杨辉三角的结构,但求最小路径和而非生成三角形LeetCode 931. 下降路径最小和Medium二维DP在二维矩阵中从上到下找最小路径,递推关系类似 课后小测试试这道变体题,不要看答案,自己先想5分钟!题目:如何只用 O(n) 空间生成杨辉三角的第 n 行?(不需要返回整个三角形) 提示(实在想不出来再点开)只需要维护当前行和上一行,用两个数组交替更新;或者用一个数组从后往前更新(避免覆盖)。✅ 参考答案defgetRow(rowIndex:int)-List[int]: 只返回杨辉三角的第 rowIndex 行(从0开始计数) 空间优化到 O(n) # 从后往前更新,避免覆盖row[1]*(rowIndex1)foriinrange(2,rowIndex1):# 从后往前更新中间元素forjinrange(i-1,0,-1):row[j]row[j]row[j-1]returnrow# 测试print(getRow(3))# 输出: [1, 3, 3, 1]print(getRow(4))# 输出: [1, 4, 6, 4, 1]核心思路:初始化长度为 rowIndex1 的数组,全部填1从第2行开始逐行更新(第0行和第1行都是全1,不需要更新)关键技巧:从后往前更新row[j] row[j] row[j-1]为什么从后往前?如果从前往后,row[j]被更新后,计算row[j1]时需要的旧值row[j]已经被覆盖了从后往前更新时,row[j-1]还是旧值,不会被覆盖举例:生成第3行 [1, 3, 3, 1]初始: row [1, 1, 1, 1]i2: j1, row[1] row[1] row[0] 11 2 → [1, 2, 1, 1]i3: j2, row[2] row[2] row[1] 12 3 → [1, 2, 3, 1]j1, row[1] row[1] row[0] 21 3 → [1, 3, 3, 1]如果这篇内容对你有帮助推荐收藏 AI Compasshttps://github.com/tingaicompass/AI-Compass更多系统化题解、编程基础和 AI 学习资料都在这里后续复习和拓展会更省时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2498625.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…