程序员面试必备的数学基础¶
覆盖:初中/高中数学核心知识点,与算法和数据分析直接相关 适用:快速复习数学基础,为算法面试和数据工程打底 方法:5W1H(为什么学、学什么、何时用、在哪用、谁在用、怎么用)
一、为什么程序员需要数学基础?¶
Why - 为什么要学?¶
1. 算法背后的数学原理
- 时间复杂度分析 → 对数、指数、级数
- 空间复杂度 → 组合数学、排列
- 概率算法 → 概率论基础
2. 面试必考
- 动态规划 → 递推关系、最优化
- 概率题 → 期望、条件概率
- 复杂度推导 → 级数求和
3. 职业发展
- 数据工程师 → 统计分析
- 机器学习 → 线性代数、微积分
- 密码学 → 数论、模运算
What - 学什么?¶
初中核心:
- 代数:方程、因式分解
- 函数:一次/二次函数
- 几何:三角形、圆
- 统计:平均数、方差、基础概率
高中核心:
- 函数与导数:指数/对数、导数应用
- 数列:等差/等比、级数求和
- 排列组合:P(n,m)、C(n,m)
- 概率:随机变量、分布、贝叶斯
- 向量与矩阵:点积、矩阵乘法
When - 何时用?¶
刷 LeetCode 时:
- 看到 O(log n) → 想到对数函数
- 看到排列组合题 → 想到 C(n,m)
- 看到概率题 → 想到期望和条件概率
分析算法复杂度时:
- 双层循环 → Σ i = O(n²)
- 二分查找 → log n
- 分治算法 → T(n) = 2T(n/2) + O(n) = O(n log n)
Where - 在哪用?¶
算法场景:
- 二分查找 → 对数函数单调性
- 动态规划 → 递推关系、最优化
- 回溯算法 → 排列组合
- 贪心算法 → 不等式、极值
- 概率算法 → 期望计算
数据工程:
- A/B 测试 → 假设检验、置信区间
- 数据质量 → 方差、标准差
- 采样算法 → 概率分布
Who - 谁在用?¶
岗位需求:
- 算法工程师 → 全量数学知识
- 数据工程师 → 统计、概率、线性代数
- 后端开发 → 复杂度分析、基础概率
- 机器学习 → 微积分、线性代数、概率论
面试官期望:
- 能推导复杂度公式
- 能解释为什么选择某个算法
- 能做概率分析
How - 怎么用?¶
学习方法:
1. 理解公式来源(为什么这样设计)
2. 配合代码实现(用 Java/Python 写出来)
3. 找 LeetCode 题目练习(至少 3 题)
4. 面试时能解释(能说清楚推导过程)
复习节奏:
- 每天 1-2 个知识点
- 每个知识点配套 2-3 道题目
- 周末复习本周内容
人类为什么需要数学?(比「面试」更深一层)¶
下面回答「数学是不是西方发明的奢侈品」——不是。数学是人在数不过来、量不准、预测不了时,被迫造出的共享语言。
1. 现实逼出来的,不是象牙塔里的爱好
| 人的处境 | 没有数学会怎样 | 数学在干什么 |
|---|---|---|
| 分粮食、分地、征税 | 吵翻、不公平 | 数与比例 |
| 盖房、丈量、治水 | 塌了、淹了 | 几何与方程 |
| 历法、航海、天文 | 误期、触礁 | 三角、周期 |
| 利滚利、人口、疫情 | 算错就破产或误判 | 指数、概率 |
| 数据太多、脑子太小 | 记不住 | 符号把经验压成可重复的规则 |
所以:数学 = 用极少的规则,描述极大的世界,并在多人之间对齐「算得一样」。
程序员里的 O(log n)、对数表、复利公式,和四千年前分田、六百年前对数表,是同一种刚需:脑子和纸笔算不动,就要找捷径。
2. 和「聪明」无关,和「可协作」有关
- 一个人可以凭直觉估一估;十万人交税、修长城、跑网络集群,必须有一套谁按同样步骤都得到同样结果的术。
- 证明、公理、符号,后来是为了减少歧义和教下一代;早期很多文明用口诀、例题、算筹步骤达到同样目的——形式不同,刚需相同。
3. 和程序员的关系(收束到本文档)
现实世界有约束(时间、内存、钱、人数)
→ 要比较「哪种做法更省」
→ 要预测「数据变大后会怎样」
→ 这就是复杂度、概率、建模
→ 背后都是数学,只是你用的是 Java 而不是算筹
一句话:人类需要数学,是因为世界可度量、可重复、可协作;数学是压缩现实 + 对齐彼此的工具,不是某国独有的装饰。
中国(东方)有没有数学?——先纠正一个常见误解¶
结论:有,而且很早、很深。
容易产生的错觉是:「课本里的定理都是希腊/欧洲名字 → 中国没数学」。那是近代课本叙事和表达方式造成的,不是历史事实。
为什么你会觉得「东方没有数学」?¶
| 原因 | 说明 |
|---|---|
| 课本叙事 | 20 世纪以来中小学、大学教材大量引进欧几里得式「定义—定理—证明」体系;中国古代文献多是应用题 + 算法步骤(术),很少用现代符号写成「定理 3.2」,看起来像没理论。 |
| 符号与术语 | 我们今天说的「几何」「代数」「函数」,多是译词;中国古代分的是算术、测圆、方程、勾股等,门类不同,不等于不存在。 |
| 高峰错开 | 中国古典数学在宋元达到很高水平;明清以后相对停滞;同时欧洲微积分、解析几何爆发——对比之下像「只有西方在前进」。 |
| 传播与话语权 | 科学史长期以欧洲为中心书写;中国成果写入全球教科书较晚(如大衍求一术、杨辉三角)。 |
中国数学史上值得记住的(和本文档相关)¶
| 时代 / 人物 | 贡献(白话) | 和算法/工程的联系 |
|---|---|---|
| 《九章算术》(约成书于汉,更早材料更早) | 分数、比例、面积体积、勾股、联立一次方程组(《方程》章) | 线性方程组、应用建模;消元思想早于西方同类系统叙述数百年 |
| 刘徽(3 世纪) | 割圆术算 π;立体体积 | 极限直觉、数值逼近 → 今天仍用「割圆/迭代」思想 |
| 祖冲之(5 世纪) | π 约 3.1415926~7,密率 355/113 | 高精度近似、分数表示 |
| 算筹、算盘 | 位值制运算工具 | 和计算机「按位运算」一样,是执行算法的硬件 |
| 杨辉三角(约 11 世纪,可更早) | 二项式系数表 | 组合数 C(n,k)、帕斯卡三角同一对象 |
| 秦九韶(13 世纪)《数书九章》 | 大衍求一术 | 中国剩余定理——密码、哈希、同余、分布式里仍常见 |
| 宋元(李冶、朱世杰等) | 天元术(设元列方程)、高次方程数值解 | 代数化、方程思维,接近「设未知数」的现代写法 |
和西方对比时,记住差异而不是「有无」:
欧洲(尤其希腊传统)偏:从少数公理推出定理,几何证明写在书上
中国古典偏:解决具体问题,给出可执行的「术」,在例题里传承
印度—阿拉伯:位值制、代数符号、三角函数表等经翻译传入欧洲
三条线都在算同一片天空、同一块地;不是东方没有数学,而是长期用另一套文体记录,且近代课堂主要教的是欧洲那套写法。
「东方」更广一点¶
- 印度:十进制位值、0 作为数、早期代数与三角;经阿拉伯传入欧洲,改变世界算术。
- 伊斯兰黄金时代(8–13 世纪):保存并发展希腊、印度、波斯数学;花拉子米的《代数学》等(见上文 §3.1 基础函数从何而来)。
- 日本、朝鲜、越南等:曾大量吸收中国算学,并有本土发展(如日本和算)。
和「程序员学数学」的关系¶
- 你学的 模运算、CRT、组合、方程组、二分/对数,在中国古典里都有 cousin(同族思想),只是符号不同。
- 自卑或对立都不必要:现代数学语言是全世界的汇合——包括中国宋元、印度数字、阿拉伯代数、欧洲分析。
一句话:
人类需要数学,因为要把复杂世界变可算、可教、可协作;
中国不仅有数学,而且曾独立解决过方程、数论、组合、数值计算等高难度问题——只是写在《九章》式的「题+术」里,不等于没出现过。
为什么明清后中国数学「相对停滞」?¶
先说清「停滞」指什么:不是明清没人算数,而是没有跟上 17 世纪以后欧洲那条「解析几何 → 微积分 → 近代科学」的爆发链,和宋元高峰比增量变慢;同时欧洲在指数级拉开差距。下面用多因素解释,避免「中国人不行」或「只差科举」这种单点归因。
不宜把明清混为一谈:明末有 西学东渐窗口;清初中期仍有 会通派;乾隆朝《四库全书》+ 明史定稿 才是「考据盛世、精英编书、禁毁并行」的集中体现——见下文 §明清要不要分开看。
1. 先纠正:明清不是「零数学」¶
| 人物 / 事件 | 说明 |
|---|---|
| 徐光启、李之藻 等 + 利玛窦 等 | 明末译 《几何原本》 前六卷,把欧氏证明体系引进中国 |
| 薛凤祚、方中通 等 | 清初吸收对数、三角、西洋算法,做 会通(中西算法对照) |
| 梅文鼎(清初) | 历算、几何、代数兼通,著书极多,是清代数学代表人物之一 |
| 程大位《算法统宗》(明) | 珠算普及教材,影响民间和商业计算 |
| 戴震、阮元 等 | 乾嘉考据中整理古算(如《畴人传》),抢救文献而非开创微积分 |
所以更准确的说法是:传统算学仍在,但未能自主完成「从术到近代数学语言」的第二次革命;西洋微积分体系进来得晚、进课堂更晚。
2. 制度与激励:算学不在「上升通道」中心¶
宋元时商业、历法、水利仍催生高次方程、天元术等新问题。
明清科举主流路径是 四书五经 + 八股,算学:
- 不进入进士考试的核心科目;
- 实用算学多服务于 钦天监历算、田赋丈量、工程估料 —— 往往是技术吏员、家学、私塾传承,而不是全国精英竞相创新的公共赛场。
结果:最聪明的一批人大量时间在 经义、考据、诗文;算学高手有,但社会声望与资源难与欧洲近代「大学 + 学会 + 出版」里的数学家相比。
欧洲(简化):商人/航海/炮术/天文 → 需要预测 → 资助数学与出版
明清(简化):帝国治理稳定后 → 算学常是「够用术」+ 宫廷历算
3. 知识形态:「术」很强,但缺一条通往微积分的桥¶
中国古典数学极擅:
- 具体问题的算法(方程消元、大衍求一、数值开方);
- 有限步骤、可手算 的术。
欧洲在 16–17 世纪形成的关键跳跃是:
- 符号代数 统一几何(笛卡尔);
- 无穷小、极限、动力学 统一运动与曲线(牛顿、莱布niz);
- 公理—证明 书写习惯与代数符号结合,便于教下一代继续叠高。
中国宋元天元术已很接近「设元列式」,但:
- 少写 「为何永远成立」 的普适证明,多写 「这道题怎么算」;
- 当欧洲整门学科转向 函数、连续、微分 时,中国一侧缺少同级别的内部语言升级,对接西洋书时就要 整本翻译、整体系改教材 —— 慢一代人。
这不是「笨」,是 问题包装 + 书写传统 不同,在近代转折点上的 转换成本 极高。
4. 需求结构:少了一类「逼出微积分」的连环压力¶
欧洲同期(重叠讲,便于记忆):
| 压力 | 逼出的数学 |
|---|---|
| 航海定位、天文 | 三角、对数、误差 |
| 炮弹弹道、力学 | 微分方程雏形 |
| 光学、真空泵 | 实验 + 量化 |
| 商业利息、人口模型 | 指数、级数 |
明清帝国:
- 农业—官僚治理 仍强,丈量、赋税、历法仍要算,但许多问题 在算筹/珠算 + 已有公式内可解;
- 没有同等规模的商业—军事—工业复合体,持续砸钱要 「预测运动、预测轨道」 的国家级竞赛(直到 19 世纪中叶鸦片战争后才痛感「算不如人」)。
数学发展常被 「什么痛苦最花钱、最要命」 驱动;明清上层社会的 最致命焦虑 往往不在「证明行星轨道」,而在 边疆、漕运、纲常、考试 —— 算学优先级随之靠后。
5. 交流与出版:欧洲在「联网」,中国在「精注旧书」¶
欧洲:印刷术普及 → 公式与证明可 cheap copy → 数学家跨城通信(如牛顿—莱布尼茨网络)→ 知识复利 快。
明清:
- 印刷也有(如《算法统宗》流传),但精英学术风尚在 考据、辑佚、注疏(乾嘉为盛)—— 对 古籍算书 极有价值,对 发明新符号体系 激励弱;
- 海禁与政策时紧时松,西洋新知识 主要靠耶稣士来华、少数士大夫译书,未变成全国中学的默认大纲(要到 洋务、戊戌、民国教育改革 才系统换轨)。
6. 时间线:不是「突然不行」,而是「别人换赛道了」¶
中国:汉—唐—宋—元 持续累加「术」的高峰
欧洲:中世纪保存希腊—阿拉伯—文艺复兴—17C 微积分 赛道切换
明清中国:在原有赛道上仍有人(梅文鼎、会通派),但全球前沿已搬到
「微积分 + 力学 + 实验科学」
→ 对比起来像「停滞」,实为「相对滞后」+「范式没跟上」
19 世纪后:林则徐、魏源「师夷长技」、洋务派办新式学堂、留学生、民国数学系 —— 几十年强力补课,说明滞后主要来自 制度与知识体系切换,不是民族智力。
7. 对照案例:日本明治 —— 说明「能追,但要换轨」¶
日本在明治初 系统引进西方数学教材、建大学、送留学生,几十年内追上;中国也在 20 世纪 出现华罗庚、陈景润等世界级成果。
启示:明清的相对停滞,是历史结构(激励 + 范式 + 传播)问题,不是「东方没有数学天赋」 —— 和上一节「中国有深厚算学」不矛盾。
8. 收束(给程序员读历史用)¶
| 误区 | 更稳的说法 |
|---|---|
| 明清中国人不会数学 | 会,且有人做中西会通,但前沿范式换了 |
| 只差一个科举 | 科举是激励结构之一,还有需求、符号、出版、科学共同体 |
| 中国从未参与现代数学 | 20 世纪起全面接入;今天用的是全球同一套符号 |
一句话:
宋元把「术」推到极高;明清精英的上升通道与帝国需求 不再逼出微积分那条链;欧洲因航海、力学、出版与公理代数 换赛道爆发;西洋数学 晚进课堂,叠加考据盛世 精研古书胜于发明新符号 —— 于是相对停滞。要追,靠的是 翻译、教育、工业与战争带来的痛感 —— 近代中国走的正是这条路。
9. 明清要不要分开看?明史、四库与数学¶
短答:不应混为一谈。 讲数学史时至少拆成 明末(开放接触)、清初(会通吸收)、乾隆及以后(大型文献工程 + 思想控制) 三段;《明史》修纂 与 《四库全书》 主要属 清代国家工程,对数学是 间接影响(占用人、定正统、毁部分书),不是「专门为消灭数学」。
9.1 为什么不宜把「明清」合成一个词?¶
| 阶段 | 大致时间 | 和数学的关系(概括) |
|---|---|---|
| 明前期—中期 | 14–16 世纪初 | 承元明初,实用算学、历算延续;程大位《算法统宗》(1593)普及珠算 |
| 明末 | 16 世纪末–1644 | 西学东渐高峰:利玛窦、徐光启译 《几何原本》(1607)等——是 主动引进 欧氏体系,不是封闭 |
| 清初 | 17 世纪 | 会通派(薛凤祚、梅文鼎等)吸收对数、三角;康熙 本人向耶稣士学天文数学 |
| 清中叶(乾隆) | 18 世纪 | 《四库全书》、《明史》定稿;考据极盛;西洋新知识 引进节奏变慢(直到鸦片战争痛感) |
粗线条:
明末 ≈ 「开窗」—— 几何原本进来
清初 ≈ 「会通」—— 梅文鼎一代
乾隆 ≈ 「编书 + 筛书」—— 四库、明史;精英时间被文献工程占满
若把 明末的开放 和 乾隆的编修+禁毁 都塞进「明清停滞」,会 冤枉明代晚期,也 看不清清代政策变化。
9.2 《明史》修纂:是什么?和数学什么关系?¶
| 项目 | 内容 |
|---|---|
| 性质 | 清朝官修的 前朝正史(二十四史之一),论证清承明统、确立 官方历史叙事 |
| 时间 | 康熙年间起步(如万斯同私修《明史稿》),雍正朝设馆,乾隆初定稿(1739) |
| 人力 | 张廷玉等总纂,大量翰林、考据学者 数十年 投入 |
| 和数学 | 不直接删算书;影响在于 占用同一批最顶尖的书生,强化 史学、义例、文献真伪 能力,而非 发明新数学 |
间接影响(要记这种「结构」):
- 国家把学术荣誉导向 「修史正确」 → 和算学 抢人、抢时间;
- 与 四库、乾嘉考据 同一套 文化治理逻辑:正本清源、定于一尊;
- 对 数学内容 几乎无「专门打压」,但对 「谁算前沿」 有 机会成本。
9.3 《四库全书》:编了什么?对算学利弊¶
是什么(1773–1782,乾隆朝):
- 征集全国图书,经学、史、子、集 四部 分类钞录;
- 子部 下有 算学 类(如《周髀》《九章算术》及刘徽等注、历代畴人著作)—— 大量古算书因编修而精校保存;
- 戴震等参与 辑校、辨伪、补阙,对古籍数学文本的 准确性 贡献很大。
正面(数学史角度):
没有四库,许多宋元明算学版本可能更散、更难读
→ 今天研究《九章》、天元术,仍依赖这一代的辑校成果
→ 这是「保存 + 校勘」,不是「创造微积分」
负面(为何仍说拖慢「前沿」):
| 机制 | 说明 |
|---|---|
| 人力虹吸 | 一流学者 十年级 投入编书、写提要、辨真伪 → 少人做会通后的新理论 |
| 禁毁书 | 同时开 《禁毁书目》,毁禁数千种;虽 不以算书为主靶子,但 异端、反清、「僭越」 类著作遭殃;整体氛围 抑制自由探讨 |
| 定正统 | 什么是「可入国库的学问」由朝廷框定 → 强化 注疏古人 而非 挑战公理体系 |
| 与欧洲不同步 | 编四库时欧洲已在 欧拉时代;中国精英在 精刻宋本,赛道差距继续拉大 |
关键区分:
- 四库对算学:抢救古籍 ≠ 推动近代化;
- 不是「四库禁止数学」,而是 国家工程的方向 把聪明人的 边际时间 押在 文献安全与正统 上。
9.4 明史 + 四库:放在一起怎么理解?¶
清代文化治理(简化):
修《明史》 → 前朝历史只能有一个官方版本
编《四库》 → 当代知识只能有一个入库标准
禁毁书目 → 异端与危险文本物理消失
对数学:
古算书 largely 被收入、校勘 → 传统算学「博物馆化」做得好
微积分、力学新范式 → 没有变成四库之后全国教材的默认下一步
和「明清混谈」的关系:
- 明史、四库主要是清中叶乾隆朝的事,不能用来解释 万历年间徐光启为什么能译《几何原本》;
- 说明 「停滞」若发生在政策层面,清 > 明,且集中在乾隆文献工程之后的社会风气,而不是整个明代都封闭。
9.5 收束表¶
| 问题 | 建议说法 |
|---|---|
| 明清能混谈吗? | 不能粗混;至少分 明末开放 / 清初会通 / 乾隆编修 |
| 明史修纂打击数学吗? | 无专门打击;间接占用精英、强化史学正统 |
| 四库对算书? | 子部算学大量保存校勘;同时 禁毁、定尊,不利于自由创新 |
| 和停滞叙事? | 停滞 = 范式没切换 + 激励结构;四库是 清代中后期「保存古算、拖慢前沿」的放大器,不是唯一原因 |
数学的乐趣在哪里?如何感知?¶
乐趣很少来自「又多背了一个公式」;多半来自 突然少算了很多步、两件看似无关的事原来是同一件事、一个猜想在脑子里长成了证明。
程序员最容易感知到的,是 复杂度从爆炸变成可算 那一刻——和纳皮尔把乘法变加法同一种爽感。
乐趣的几种「味道」(不必全开,有一种就够)¶
| 味道 | 是什么感觉 | 例子(程序员向) |
|---|---|---|
| 省力 | 原来要算 100 步,现在 7 步 | 二分 O(log n):每次减半;对数表:乘变加 |
| 统一 | 三个问题其实是同一道题 | 排雷、盛水、对账都是双指针;eˣ 与 ln x 互逆 |
| 必然 | 不是凑答案,是「只能这样」 | 勾股定理;「排序比较下界」Ω(n log n) |
| 构造 | 自己造出一个能用的东西 | 写出一个 DP 状态;用 CRT 拼回整数 |
| 极限/逼近 | 越来越准,且知道误差去哪 | 刘徽割圆;数值迭代;A/B 检验置信区间 |
| 游戏 | 规则简单,组合爆炸,仍可控 | 数独、概率谜题;LeetCode 当谜题而非 KPI |
和「考试/面试」的关系:面试考的是 省力 + 统一(模板、复杂度);乐趣若只绑在 通过率 上,容易枯竭。把乐趣绑在「我少想了一步却做对了」,续航更长。
如何感知?——从身体到符号,四层阶梯¶
很多人「感觉不到乐趣」,是因为只见过 符号层,没见过下面三层。可以 刻意往下走一层。
第 4 层 符号:公式、证明、代码模板 ← 课本、面试默认在这
第 3 层 结构:为什么 O(n log n)、为何互逆
第 2 层 图像/数量:画曲线、列表规模翻一倍会怎样
第 1 层 动作/故事:折纸、对账、减半查找、纳皮尔造表
感知练习(每次 5~15 分钟,任选):
- 数量感:
n=1000时,n、n log n、n²、2ⁿ各多大?用计算器点一次,记住数量级差距——乐趣常在「原来 2ⁿ 这么恐怖,所以我要用 log」。 - 画一张图:指数上扬、对数平缓;或双指针在数组上走三步——眼睛比符号快。
- 讲一个人话故事:纳皮尔为何花 20 年——「乘法太累」;你为何用二分——「猜数字每次砍一半」。
- 一道题只追求一种爽:今天不刷题量,只求 「我发现这和昨天那题是同一类」(统一感)。
- 写三行代码看运行:CRT、二分、快速幂——机器替你验证「必然」,比干看公式踏实。
感知不到的常见原因(不是你的错):
| 原因 | 对策 |
|---|---|
| 只见过刷题 KPI | 设 「今日一种乐趣」 即可,见 数据结构与算法·低电量模式 |
| 符号没接上故事 | 读本文档 §3.1 基础函数从何而来 |
| 疲劳 | 乐趣在 清醒边缘 最明显;晕时只做 复习一种已懂的味道 |
| 以为乐趣 = 天赋 | 乐趣多是 练出模式识别;同一类题见第三次会突然「变轻」 |
和「人类为什么需要数学」连起来¶
- 需要数学 = 现实逼你省力、协作、预测。
- 乐趣数学 = 大脑发现 「规则压缩了世界」 时的奖赏——多巴胺常出现在 「原来可以这样想」,不是 「又背了一条」。
对数据开发/计费的你:对账、聚合、窗口、采样 里都有 统一与省力;算法面试里的 双指针、哈希、二分 是同一套奖赏的 小游戏版本。
今日 10 分钟「尝乐趣」(不做题版)¶
1. 想一件你工作中「算不动」的事(对账、去重、查区间)
2. 问:若数据排序了,能否少扫一遍?→ 二分或双指针故事
3. 在纸上画 6 个数的数组,标两个指针走 2 步
4. 停。写下一句:今天我感知到的是「省力」还是「统一」?
一句话:数学的乐趣在 压缩、统一、必然、可构造;感知方式是 先数量、再图像、再故事、最后符号——和纳皮尔、刘徽、欧拉经历的是同一种爽,只是你现在用 Java 和 O(log n) 来写。
乐趣容易诱发深挖:尝过「统一感」后想一口气读完明清史、推完所有公式——请用 数据结构与算法·克制深挖 里的 停车场 + 够用止损,把乐趣留在 周末时间盒,别占每日主线。
二、初中数学核心(5W1H 展开)¶
2.1 代数基础¶
方程与不等式¶
Why - 为什么要学?
面试中涉及数学推导的题目需要方程求解能力。
例如:优化问题中找到最优解、递推关系求通项。
What - 核心公式是什么?
一元二次方程:ax² + bx + c = 0
求根公式:x = (-b ± √(b² - 4ac)) / 2a
判别式:Δ = b² - 4ac
- Δ > 0:两个不等实根
- Δ = 0:两个相等实根
- Δ < 0:无实根
韦达定理:
x₁ + x₂ = -b/a
x₁ × x₂ = c/a
When - 什么时候用?
- LeetCode 中涉及数学推导
- 动态规划状态转移方程求解
- 最优化问题找极值
Where - 在哪些场景用?
算法题:
- "两数之和" → 方程思维
- "盛最多水的容器" → 最优化
- "接雨水" → 方程建模
数据工程:
- 成本优化模型
- 资源分配问题
Who - 谁会考你?
面试官常见问题:
- "这个时间复杂度是怎么推导出来的?"
- "能不能给出一个数学证明?"
- "有没有更优的解法?"
How - 怎么用?(代码示例)
// Java 实现:求解一元二次方程
public class QuadraticSolver {
public static double[] solve(double a, double b, double c) {
double delta = b * b - 4 * a * c;
if (delta < 0) {
return new double[]{}; // 无实根
} else if (delta == 0) {
double x = -b / (2 * a);
return new double[]{x}; // 一个根
} else {
double x1 = (-b + Math.sqrt(delta)) / (2 * a);
double x2 = (-b - Math.sqrt(delta)) / (2 * a);
return new double[]{x1, x2}; // 两个根
}
}
public static void main(String[] args) {
double[] roots = solve(1, -3, 2); // x² - 3x + 2 = 0
for (double x : roots) {
System.out.println("x = " + x); // x = 2.0, x = 1.0
}
}
}
因式分解¶
Why - 为什么要学?
因式分解能简化计算,优化算法时间复杂度。
例如:把 O(n) 的循环变成 O(1) 的公式计算。
What - 核心公式是什么?
1. 平方差:a² - b² = (a+b)(a-b)
2. 完全平方:a² ± 2ab + b² = (a±b)²
3. 立方和/差:a³ ± b³ = (a±b)(a² ∓ ab + b²)
When - 什么时候用?
- 优化循环计算
- 减少时间复杂度
- 数学推导简化
Where - 在哪些场景用?
LeetCode 题目:
- "连续整数求和" → 用等差数列求和公式
- "完全平方数" → 因式分解判断
数据工程:
- 批量计算优化
- 聚合查询加速
Who - 谁会考你?
面试官可能问:
- "这个计算能不能优化到 O(1)?"
- "有没有数学公式可以直接用?"
How - 怎么用?(代码示例)
// 优化前:O(n) 循环求和
public int sumSlow(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
return sum;
}
// 优化后:O(1) 公式计算
public int sumFast(int n) {
return n * (n + 1) / 2; // 等差数列求和公式
}
2.2 函数基础¶
一次函数与二次函数¶
Why - 为什么要学?
函数的单调性判断是二分查找、三分查找的基础。
最优化问题需要找函数的极值点。
What - 核心公式是什么?
一次函数:y = kx + b
- 斜率 k = (y₂-y₁)/(x₂-x₁)
- 截距 b(与 y 轴交点)
- 单调性:k>0 递增,k<0 递减
二次函数:y = ax² + bx + c
- 顶点:(-b/2a, (4ac-b²)/4a)
- 对称轴:x = -b/2a
- 开口方向:a>0 向上,a<0 向下
When - 什么时候用?
- 二分查找判断单调性
- 最优化问题找极值
- 算法复杂度分析
Where - 在哪些场景用?
LeetCode 题目:
- "寻找峰值" → 函数单调性
- "最小化去加油站的最大距离" → 二分答案
数据工程:
- 成本函数优化
- 资源分配最优化
Who - 谁会考你?
面试官可能问:
- "这个函数是单调的吗?为什么?"
- "能不能用二分查找优化?"
How - 怎么用?(代码示例)
// 二分查找应用:寻找峰值
// 前提:函数在某个区间内单调
public int findPeak(int[] nums) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < nums[mid + 1]) {
left = mid + 1; // 右侧递增,峰值在右边
} else {
right = mid; // 左侧递减,峰值在左边
}
}
return left;
}
2.3 几何基础¶
平面几何¶
Why - 为什么要学?
计算几何题目需要几何知识。
图形学、碰撞检测、路径规划都依赖几何。
What - 核心公式是什么?
三角形:
- 面积:S = ½ × 底 × 高
- 勾股定理:a² + b² = c²(直角三角形)
- 余弦定理:c² = a² + b² - 2ab·cosC
圆:
- 周长:C = 2πr
- 面积:S = πr²
When - 什么时候用?
- LeetCode 计算几何题
- 图形渲染
- 碰撞检测
- 路径规划
Where - 在哪些场景用?
LeetCode 题目:
- "有效的正方形" → 勾股定理
- "最大三角形面积" → 面积公式
- "圆和矩形相交" → 几何判断
游戏开发:
- 碰撞检测
- 弹道计算
Who - 谁会考你?
面试官可能问:
- "怎么判断两个矩形是否相交?"
- "怎么计算点到直线的距离?"
How - 怎么用?(代码示例)
// 判断三点是否能构成三角形(任意两边之和大于第三边)
public boolean isValidTriangle(double a, double b, double c) {
return (a + b > c) && (a + c > b) && (b + c > a);
}
// 计算两点距离(勾股定理)
public double distance(double x1, double y1, double x2, double y2) {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
2.4 统计与概率¶
基础统计¶
Why - 为什么要学?
数据分析、A/B 测试、质量监控都需要统计知识。
面试中经常问数据分布和异常检测。
What - 核心公式是什么?
集中趋势:
- 平均数:x̄ = Σxᵢ/n
- 中位数:排序后中间的数
- 众数:出现次数最多的数
离散程度:
- 方差:σ² = Σ(xᵢ-x̄)²/n
- 标准差:σ = √σ²
- 极差:max - min
When - 什么时候用?
- 数据分析
- A/B 测试
- 质量监控
- 异常检测
Where - 在哪些场景用?
数据工程:
- 数据质量巡检
- 指标异常告警
- 用户行为分析
机器学习:
- 特征工程
- 数据标准化
Who - 谁会考你?
面试官可能问:
- "怎么判断数据是否有异常?"
- "均值和中位数哪个更适合描述这组数据?"
How - 怎么用?(代码示例)
// 计算平均数和方差
public class Statistics {
public static double mean(double[] nums) {
double sum = 0;
for (double n : nums) sum += n;
return sum / nums.length;
}
public static double variance(double[] nums) {
double m = mean(nums);
double sum = 0;
for (double n : nums) {
sum += Math.pow(n - m, 2);
}
return sum / nums.length;
}
public static double stdDev(double[] nums) {
return Math.sqrt(variance(nums));
}
}
基础概率¶
Why - 为什么要学?
概率题是面试高频题型。
随机算法、蒙特卡洛方法都依赖概率知识。
What - 核心公式是什么?
概率定义:P(A) = 事件 A 发生的次数 / 总试验次数
基本公式:
1. 互斥事件:P(A∪B) = P(A) + P(B)
2. 独立事件:P(A∩B) = P(A) × P(B)
3. 条件概率:P(A|B) = P(A∩B) / P(B)
4. 全概率公式:P(B) = Σ P(B|Aᵢ)·P(Aᵢ)
When - 什么时候用?
- LeetCode 概率题
- 随机算法
- A/B 测试
- 风险评估
Where - 在哪些场景用?
LeetCode 题目:
- "硬币游戏"
- "随机数生成器"
- "概率最大路径"
数据工程:
- 用户转化漏斗
- 风险评估模型
Who - 谁会考你?
面试官经典题:
- "掷两个骰子,点数和为 7 的概率是多少?"
- "已知某事件发生了,求另一个事件的条件概率"
How - 怎么用?(代码示例)
// 计算两个事件同时发生的概率(独立事件)
public double jointProbability(double pA, double pB) {
return pA * pB; // P(A∩B) = P(A) × P(B)
}
// 计算条件概率
public double conditionalProbability(double pAB, double pB) {
return pAB / pB; // P(A|B) = P(A∩B) / P(B)
}
三、高中数学核心(5W1H 展开)¶
3.1 函数与导数¶
基础函数从何而来?(历史与人物)¶
重要前提:没有一位神仙某天宣布「今天发明对数」。
多数是 几百年里,很多人为解决具体痛苦(算不动、测不准、利滚利) 慢慢凑出来的工具;后来 Euler、Leibniz 等人才把符号写统一。
为啥需要「函数」这个概念?¶
函数 = 输入一个数,按固定规则得到另一个数:y = f(x)。
| 时代的痛苦 | 需要什么 |
|---|---|
| 丈量土地、盖房子 | 长度与面积的关系 |
| 天文、航海 | 角度与高度、周期 |
| 贸易、利息 | 本金与时间的关系 |
| 炮弹、行星 | 变化有多快(后来的微积分) |
| 大数乘除 | 把乘变成加(对数) |
「函数」这个词:Leibniz(莱布尼茨,17 世纪末)用 f(x) 这种写法;Euler(欧拉,18 世纪)把指数、对数、三角写进统一体系。
程序员今天用的,是三四百年前算表、天文、工程问题的遗产。
各类基础函数:谁、为啥、经历了啥(一张总表)¶
| 函数类型 | 典型式子 | 最初在解决什么 | 关键人物 / 时代 | 和算法的关系 |
|---|---|---|---|---|
| 常数 | y = c |
不变量 | 自古就有 | O(1) |
| 一次(线性) | y = kx + b |
匀速、按比例变化 | 古埃及、巴比伦度量 | 线性扫描 O(n) |
| 二次 | y = ax² + bx + c |
面积(正方形边长→面积)、抛物运动 | 巴比伦 ~2000 年前;代数解法的系统化 花拉子米(9 世纪) | O(n²) 两重循环 |
| 多项式 / 幂 | y = xⁿ |
体积、更高次几何 | 古希腊;17 世纪代数符号成熟 | O(n^k) |
| 有理式 | 分式 | 比例分配、平均速度 | 随代数发展 | 常数因子 |
| 三角 | sin, cos | 天文、日晷、航海测角、周期现象 | 巴比伦星表;希腊 希帕恰斯;印度、阿拉伯学者完善 | 周期性、几何题 |
| 指数 | y = aˣ |
复利、人口增长、放射性——「每期乘固定倍数」 | 17 世纪利息问题;欧拉 把 e 和 eˣ 讲透(18 世纪) |
O(2ⁿ)、O(kⁿ) |
| 对数 | y = log_a x |
把乘法变加法,大数算表、天文 | 纳皮尔(1614);比吉、布里格斯(常用底 10) | O(log n)、二分 |
| 自然对数 ln | ln x |
与 eˣ 配套,微积分最简 |
欧拉;Mercator 级数(1668) | Σ 1/i ≈ ln n |
| 反函数 | log 与 exp 互逆 | 一种运算的「撤销」 | 纳皮尔时代已隐含;欧拉系统化 | 二分 ↔ 倍增 |
重点故事 1:对数——纳皮尔(John Napier)经历了啥?¶
时间:1614 年出版《奇妙对数表的描述》(拉丁文原名 Mirifici Logarithmorum Canonis Descriptio)。
他是谁:苏格兰贵族、数学家,同时代的天文学很依赖 开普勒 的行星表——里面全是大量乘除。
他的痛苦(你要记住的动机):
要做: 1234567 × 8901234
没有计算器,只有纸笔 → 极易错、极耗时
他的想法(革命性):
若有一张表,把每个数
x映到L(x),使得
L(x × y) = L(x) + L(y)
则 乘法变加法,除法变减法。
L(x) 就是后来的 对数。
他花了大约 20 年 造表、打磨方法(不是拍脑袋一天搞定)。
之后:
- 瑞士钟表匠 比吉(Jost Bürgi) 约 1610 年独立做出类似思想(出版稍晚)
- 英国 亨利·布里格斯(Henry Briggs) 把系统改成大家熟悉的 以 10 为底(常用对数),并和纳皮尔合作
- 对数表一直用到 20 世纪计算器 才退居幕后
和程序员的联系:
二分查找「每次减半」是在数 几次除 2——这就是 log₂ n 的灵魂;纳皮尔当年是在数 几次乘除能变成加。
重点故事 2:指数与自然常数 e——欧拉(Leonhard Euler)经历了啥?¶
指数 思想更早:复利、棋盘放麦粒(每格翻倍)古希腊就有传说。
问题形状:
银行复利:本金 1,年利率 100%,一年结一次 → 2
若一年结 n 次: (1 + 1/n)ⁿ
n 越来越大 → 会趋近一个常数 ≈ 2.71828… = e
欧拉(1707–1783,瑞士) 的贡献(概括):
- 用
e命名这个常数,研究eˣ与ln x - 证明
eˣ与ln x互为反函数(现代课本写法很多来自欧拉传统) - 写出
e^(iπ) + 1 = 0等,把指数、三角、复数连成一张网
他经历了啥(人物侧写,帮助记忆):
- 一生高产到离谱(论文/著作体量惊人),部分时间 失明后仍口算写作
- 在圣彼得堡、柏林等地工作,解决 航海、力学、数论、天文 里的大量「算不动」问题
- 对程序员:
O(eⁿ)和O(2ⁿ)在复杂度里同属指数级;工程里更常写2ⁿ(二进制)
重点故事 3:一次、二次、三角——更早的「基础函数」¶
一次函数 y = kx + b
- 场景:匀速走路——时间 × 速度 = 路程
- 历史:商业、税收、土地测量里比比皆是;不必归功于单人
二次函数
- 场景:边长 × 边长 = 面积;抛体高度随时间近似抛物线
- 历史:巴比伦泥板上有二次方程思想;花拉子米(al-Khwarizmi,约 820 年《代数学》)系统化一元二次(「代数」一词来自其名)
- 经历:伊斯兰黄金时代保存并发展希腊、印度数学,再传回欧洲
三角函数
- 场景:只知道角度,要算塔高、星体位置、周期
- 历史:巴比伦天文;希腊 希帕恰斯(约公元前 150 年)造弦表(三角前身);印度 阿耶波多 等发展;阿拉伯学者 阿尔·巴塔尼 推进
- 经历:航海大发现时代(15–17 世纪)极度依赖三角表,与对数表 一起 减少海难
发散小结:不是「谁发明了函数」,而是「一类类问题逼出工具」¶
土地测量 → 一次、二次、几何
天文航海 → 三角
复利增长 → 指数
大数运算 → 对数(纳皮尔 20 年磨表)
统一符号 → 莱布尼茨 f(x)、欧拉 eˣ 与 ln x
计算机时代 → 我们拿它们数「操作次数」→ O(log n)、O(2ⁿ)
一句话:
对数 是纳皮尔等人为了让 乘除变加减;
指数 是复利、增长问题里 反复乘同一个数;
一次/二次/三角 是测量、天文、工程里 现实世界的关系;
Euler、Leibniz 后来把这些写进 同一套语言,你才在高中和复杂度里见到它们。
指数函数与对数函数(重点专题 · 算法向)¶
程序员最常用的一对函数:指数 = 爆炸式增长,对数 = 反复减半。
复杂度里O(2ⁿ)、O(log n)、O(n log n)都从这里来。
上面 纳皮尔 / 欧拉 的故事是「人话起源」;下面是「面试向公式与推导」。
读前 30 秒:先建立直觉¶
| 函数 | 一句话 | 算法里的脸 |
|---|---|---|
指数 aˣ |
每走一步 乘以固定倍数 | 暴力回溯 O(2ⁿ)、分治层数 2^h |
对数 log_a x |
问「要乘几次 a 才到 x」= 反复除到 1 要几步 | 二分 O(log n)、树高 log n |
| 互为反函数 | 指数「涨」,对数「数涨了几层」 | log_a(aˣ) = x |
n = 1024 时(数量级感受):
log₂ n = 10 ← 二分最多约 10 次
n = 1024 ← 扫一遍
n log n ≈ 10⁴ ← 排序
n² ≈ 10⁶
2ⁿ ≈ 10³⁰⁸ ← 直接不可做
1. 指数函数 y = aˣ(a > 0, a ≠ 1)¶
定义:底数 a 固定,指数 x 变,结果按 幂次 增长。
| 底数 a | 图像趋势 | 例子 |
|---|---|---|
| a > 1 | 递增,且越往后涨得越猛 | 2ˣ, 10ˣ, eˣ |
| 0 < a < 1 | 递减 | 0.5ˣ(可写成 2⁻ˣ) |
常用写法:
2ⁿ:计算机里最常见(二进制、子问题翻倍)eˣ:自然指数,\ln x以e为底(微积分、ML)- 增长:指数 >> 多项式 >> 对数(n 稍大就碾压)
算法对应:
| 表达式 | 含义 | 场景 |
|---|---|---|
O(2ⁿ) |
n 每 +1,工作量 ×2 | 子集枚举、暴力回溯 |
O(kⁿ) |
每步 k 种选择 | 排列/搜索树分支因子 k |
2^h |
树高 h 的满二叉树节点数 | 递归树节点上界 |
数值直觉(n 从 10 到 20,2ⁿ 翻 1024 倍):
| n | 2ⁿ |
|---|---|
| 10 | 1,024 |
| 15 | 32,768 |
| 20 | 1,048,576 |
| 30 | ≈ 10⁹ |
所以面试常说:n > 20 的 O(2ⁿ) 基本别想跑完。
2. 对数函数 y = log_a x(a > 0, a ≠ 1, x > 0)¶
定义:log_a x = y 等价于 aʸ = x。
人话:把 x 每次 除以 a,除到 ≤ 1 一共几步,就是 log_a x。
log₂ 8 = 3 因为 8 → 4 → 2 → 1,除 2 共 3 次
log₂ 1024 = 10 因为 2¹⁰ = 1024
| 底数 | 记号 | 谁在用 |
|---|---|---|
| 底 2 | log₂ n 或 lg n |
算法、二分、树高(计算机默认思维) |
| 底 10 | log₁₀ n |
数量级、科学计数 |
| 底 e | ln x |
微积分、\sum 1/i ≈ ln n |
换底公式(面试可一笔带过):
log_a b = log_c b / log_c a
所以 O(log₂ n) 与 O(log₁₀ n) 只差常数因子 → 大 O 里都写成 O(log n)
核心性质(推导复杂度必用):
| 性质 | 公式 | 算法用处 |
|---|---|---|
| 积变和 | log_a(xy) = log_a x + log_a y |
分治:T(n)=2T(n/2)+O(n) → 层数相加 |
| 商变差 | log_a(x/y) = log_a x - log_a y |
规模缩小 |
| 幂次提出 | log_a(xᵏ) = k · log_a x |
n² 的对数级仍是 O(log n) 量级(常数不同) |
| 底数换常数 | 换底公式 | 底 2/10/e 不影响 Big O |
3. 指数与对数:互为反函数(一张图记住)¶
y
│ y = 2ˣ (指数:x 走一点,y 跳很多)
│ ╱
│ ╱
│ ╱ y = log₂ x (对数:要 y 才翻倍,x 要乘 2)
│╱___________
└────────────── x
沿 y=x 对称 → 互为反函数
log_a(aˣ) = x
a^(log_a x) = x
程序员版对应:
- 指数:问题规模 +1 → 工作量 ×2(爆炸)
- 对数:问题规模 ÷2 → 工作量 +1 层(二分、平衡树一层一层削)
4. 复杂度增长:为什么是这个顺序?¶
O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(n³) < O(2ⁿ) < O(n!)
| 复杂度 | 数学本质 | n=10⁶ 量级直觉 |
|---|---|---|
O(log n) |
log₂ 10⁶ ≈ 20 |
二十步量级 |
O(n) |
线性 | 一百万 |
O(n log n) |
n × log n |
约两千万次操作 |
O(n²) |
平方 | 10¹²(易爆) |
O(2ⁿ) |
指数 | 不可接受 |
O(n log n) 从哪来?(归并/快排)
每一层处理约 n 个元素,共约 log₂ n 层(每次规模减半)
→ 总工作量 ≈ n × log n
5. 手把手:为什么二分查找是 O(log n)?¶
过程:有序数组长度 n,每次看中间,丢掉一半。
n → n/2 → n/4 → … → 1
设一共 k 步:n / 2ᵏ ≈ 1 → 2ᵏ ≈ n → k ≈ log₂ n
// 二分查找
public int binarySearch(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) left = mid + 1; // 丢掉左半
else right = mid - 1; // 丢掉右半
}
return -1;
}
// 循环次数 ≈ ⌊log₂ n⌋ + 1
推广:
| 操作 | 为何是 log n |
|---|---|
| 平衡 BST 查找 | 树高 h ≈ log n,每层 O(1) |
堆 push/pop |
沿树高调整 ≈ log n |
| B+ 树索引 | 层数少,每层一页,层数 ∝ log n |
| 倍增(翻倍扩容) | 容量 1,2,4,…,n 共 O(log n) 次扩容 |
6. 手把手:为什么分治常是 O(n log n)?¶
模型:T(n) = 2T(n/2) + O(n)(归并排序、快排平均)
规模: n
/ \
n/2 n/2 ← 一层:合并代价 O(n)
/ \ / \
... ... ← 共约 log₂ n 层
每层总工作量 ≈ O(n)
层数 ≈ log₂ n
→ T(n) = O(n log n)
若变成 T(n) = 2T(n/2) + O(1)(只分不合并)→ O(n)。
若变成 T(n) = 2T(n/2) + O(n²) → O(n² log n)。
7. 常见误区¶
| 误区 | 正解 |
|---|---|
O(log n) 和 O(lg n) 不一样 |
算法里常指同阶,底只影响常数 |
log n 比 n 大 |
错,n 足够大时 log n ≪ n |
O(2n) 是指数 |
2n = O(n),指数是 O(2ⁿ),底在指数上 |
| 二分一定 O(log n) | 前提:有序 + 随机访问;链表二分仍是 O(n) 找中点 |
8. Java 里怎么写 / 怎么算¶
// 以 2 为底的对数(算二分步数上界)
int steps = (int) (Math.log(n) / Math.log(2)); // ≈ log₂ n
// 自然对数 ln
double ln = Math.log(x); // 默认 e 为底
// 判断 n 是否是 2 的幂
boolean isPowerOfTwo(int n) {
return n > 0 && (n & (n - 1)) == 0;
}
// 若 n = 2^k,则 log₂ n = k(整数)
// 复杂度对比实验(感受增长)
void compareGrowth(int n) {
System.out.println("n=" + n);
System.out.println("log2(n) ≈ " + (Math.log(n) / Math.log(2)));
System.out.println("n log n ≈ " + n * (Math.log(n) / Math.log(2)));
// 2^n 用 long 很快溢出,勿对大的 n 直接算
}
9. 5W1H 速记(面试用)¶
Why:分析「规模变大时慢多少」——指数爆炸、对数削层。
What:
- 指数:
aˣ,倍增 - 对数:
log_a x,除 a 几次到 1 - 顺序:
1 < log n < n < n log n < n² < 2ⁿ
When:见二分、树、分治、枚举子集、问复杂度。
Where:二分、BST/B+ 树、排序、回溯剪枝、DP 状态数估算。
Who:面试官问「复杂度多少」「能否优化」「为什么 log n」。
How:规模减半 → log n;规模翻倍层数 → 2^h;每层扫 n → n log n。
其他常见函数(简表)¶
| 函数 | 要点 | 算法 |
|---|---|---|
幂函数 xⁿ |
n²、n³ 多项式 | 双重循环、三重循环 |
一次 kx+b |
单调性 | 二分答案前提 |
二次 ax²+bx+c |
顶点、开口 | 抛物线最值题 |
导数(与指数/对数衔接)¶
(eˣ)' = eˣ
(ln x)' = 1/x ← 解释 ln 增长比 x 慢:导数 1/x → 0
(2ˣ)' = 2ˣ ln 2
(log_a x)' = 1 / (x ln a)
用途:判断函数增减、最优化(梯度下降);算法面试 复杂度用离散 log/指数 更多,导数了解即可。
3.2 数列与级数¶
等差数列¶
Why - 为什么要学?
等差数列求和公式可以把 O(n) 循环优化到 O(1)。
前缀和、批量计算都依赖这个公式。
What - 核心公式是什么?
通项公式:aₙ = a₁ + (n-1)d
前 n 项和:Sₙ = n(a₁ + aₙ)/2 = n·a₁ + n(n-1)d/2
性质:
- 任意两项之差为常数 d
- 求和时间复杂度 O(1)
When - 什么时候用?
- 前缀和计算
- 批量数据求和
- 优化循环
Where - 在哪些场景用?
LeetCode 题目:
- "等差数列划分"
- "连续子数组的最大和"
- "前缀和" 类题目
数据工程:
- 批量聚合计算
- 指标预计算
Who - 谁会考你?
面试官可能问:
- "这个求和能不能用公式优化?"
- "时间复杂度能从 O(n) 降到 O(1) 吗?"
How - 怎么用?(代码示例)
// 优化前:O(n)
public int sumArithmeticSlow(int a1, int d, int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += a1 + i * d;
}
return sum;
}
// 优化后:O(1)
public int sumArithmeticFast(int a1, int d, int n) {
int an = a1 + (n - 1) * d; // 末项
return n * (a1 + an) / 2; // 求和公式
}
等比数列¶
Why - 为什么要学?
分治算法的时间复杂度分析需要等比数列求和。
递归树的高度分析也用到这个知识。
What - 核心公式是什么?
通项公式:aₙ = a₁·qⁿ⁻¹
前 n 项和:Sₙ = a₁(1-qⁿ)/(1-q) (q≠1)
无穷等比级数(|q|<1):
S = a₁/(1-q)
典型应用:
分治算法 T(n) = 2T(n/2) + O(n)
递归树高度:log n
每层工作量:O(n)
总复杂度:O(n log n)
When - 什么时候用?
- 分治算法复杂度分析
- 递归树求和
- 等比增长问题
Where - 在哪些场景用?
LeetCode 题目:
- "汉诺塔问题"
- "分治算法类题目"
- "递归树分析"
算法设计:
- 归并排序 O(n log n)
- 快速排序 O(n log n)
Who - 谁会考你?
面试官可能问:
- "归并排序为什么是 O(n log n)?"
- "能不能画一下递归树?"
How - 怎么用?(代码示例)
// 归并排序复杂度分析
// T(n) = 2T(n/2) + O(n)
// = 2[2T(n/4) + O(n/2)] + O(n)
// = 4T(n/4) + 2O(n)
// = 8T(n/8) + 3O(n)
// = ...
// = nT(1) + log n · O(n)
// = O(n log n)
// 等比数列求和验证:
// 第 k 层工作量:2^k · O(n/2^k) = O(n)
// 共 log n 层
// 总工作量:O(n) · log n = O(n log n)
3.3 排列组合¶
Why - 为什么要学?
回溯算法、组合问题、子集问题都依赖排列组合。
动态规划状态转移也常用组合数学。
What - 核心公式是什么?
排列(有序):
P(n,m) = n!/(n-m)!
全排列:P(n,n) = n!
组合(无序):
C(n,m) = n!/[m!(n-m)!]
性质:
1. C(n,m) = C(n,n-m)
2. C(n,m) = C(n-1,m-1) + C(n-1,m) (杨辉三角)
When - 什么时候用?
- LeetCode 排列组合题目
- 回溯算法
- 动态规划
- 概率计算
Where - 在哪些场景用?
LeetCode 题目:
- "全排列" → P(n,n)
- "组合总和" → C(n,m)
- "子集" → C(n,0) + C(n,1) + ... + C(n,n) = 2ⁿ
Who - 谁会考你?
面试官可能问:
- "有多少种不同的排列方式?"
- "能不能用动态规划优化回溯?"
How - 怎么用?(代码示例)
// 计算组合数 C(n,m)
public long combination(int n, int m) {
if (m < 0 || m > n) return 0;
if (m == 0 || m == n) return 1;
if (m > n / 2) m = n - m; // 利用 C(n,m) = C(n,n-m)
long result = 1;
for (int i = 1; i <= m; i++) {
result = result * (n - i + 1) / i;
}
return result;
}
// 全排列(回溯)
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
backtrack(result, new ArrayList<>(), nums, new boolean[nums.length]);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> temp,
int[] nums, boolean[] used) {
if (temp.size() == nums.length) {
result.add(new ArrayList<>(temp));
return;
}
for (int i = 0; i < nums.length; i++) {
if (used[i]) continue;
used[i] = true;
temp.add(nums[i]);
backtrack(result, temp, nums, used);
temp.remove(temp.size() - 1);
used[i] = false;
}
}
3.4 概率论进阶¶
随机变量¶
Why - 为什么要学?
期望 DP 是面试难题。
随机算法分析需要期望和方差知识。
What - 核心公式是什么?
离散型随机变量:
- 期望:E(X) = Σ xᵢ·pᵢ
- 方差:D(X) = E[(X-E(X))²] = E(X²) - [E(X)]²
性质:
- E(aX + b) = a·E(X) + b
- D(aX + b) = a²·D(X)
- 独立变量:E(X+Y) = E(X) + E(Y)
When - 什么时候用?
- LeetCode 期望 DP 题
- 随机算法分析
- 风险评估
Where - 在哪些场景用?
LeetCode 题目:
- "掷骰子的期望"
- "随机指针"
- "期望 DP 类题目"
数据工程:
- 用户行为建模
- 转化率预估
Who - 谁会考你?
面试官经典题:
- "一个骰子掷出点数的期望是多少?"
答:E = (1+2+3+4+5+6)/6 = 3.5
How - 怎么用?(代码示例)
// 计算掷骰子的期望
public double expectedValue(int[] values, double[] probabilities) {
double expectation = 0;
for (int i = 0; i < values.length; i++) {
expectation += values[i] * probabilities[i];
}
return expectation;
}
// 使用:骰子点数 1-6,概率各 1/6
public double diceExpectedValue() {
int[] values = {1, 2, 3, 4, 5, 6};
double[] probs = {1.0/6, 1.0/6, 1.0/6, 1.0/6, 1.0/6, 1.0/6};
return expectedValue(values, probs); // 3.5
}
3.5 向量与矩阵¶
向量基础¶
Why - 为什么要学?
机器学习特征向量、相似度计算、推荐系统都用向量。
点积可以计算相似度(余弦相似度)。
What - 核心公式是什么?
向量点积:a·b = Σ aᵢbᵢ = |a||b|cosθ
余弦相似度:
cosθ = (a·b) / (|a|·|b|)
- 取值范围:[-1, 1]
- 1:完全相同
- 0:正交(无关)
- -1:完全相反
When - 什么时候用?
- 推荐系统
- 相似度计算
- 机器学习特征
Where - 在哪些场景用?
LeetCode 题目:
- "两个向量的夹角"
- "相似度计算"
数据工程:
- 用户画像相似度
- 商品推荐
- 文本相似度
Who - 谁会考你?
面试官可能问:
- "怎么计算两个用户的相似度?"
- "余弦相似度和欧氏距离有什么区别?"
How - 怎么用?(代码示例)
// 计算两个向量的点积
public double dotProduct(double[] a, double[] b) {
if (a.length != b.length) throw new IllegalArgumentException();
double sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i] * b[i];
}
return sum;
}
// 计算余弦相似度
public double cosineSimilarity(double[] a, double[] b) {
double dot = dotProduct(a, b);
double normA = Math.sqrt(dotProduct(a, a));
double normB = Math.sqrt(dotProduct(b, b));
return dot / (normA * normB);
}
3.6 数学归纳法¶
Why - 为什么要学?
证明算法正确性。
证明递推关系的通项公式。
面试中要求你证明某个结论。
What - 证明步骤是什么?
1. 基础步骤:验证 n=1 时命题成立
2. 归纳步骤:假设 n=k 时成立,证明 n=k+1 时也成立
When - 什么时候用?
- 算法正确性证明
- 递推关系证明
- 面试证明题
Where - 在哪些场景用?
LeetCode 题目:
- 需要证明正确性的题目
- 动态规划状态转移证明
算法设计:
- 递归算法证明
- 数学推导题
Who - 谁会考你?
面试官可能问:
- "你能证明这个算法是正确的吗?"
- "为什么这个递推公式成立?"
How - 怎么用?(代码示例)
// 用数学归纳法证明:1+2+...+n = n(n+1)/2
// 基础步骤:n=1
// 左边 = 1
// 右边 = 1×2/2 = 1
// 左边 = 右边,成立
// 归纳步骤:假设 n=k 时成立
// 1+2+...+k = k(k+1)/2
// 证明 n=k+1 时也成立
public class InductionProof {
// 用代码验证(非严格证明)
public static boolean verifyFormula(int n) {
int sum1 = 0;
for (int i = 1; i <= n; i++) {
sum1 += i;
}
int sum2 = n * (n + 1) / 2;
return sum1 == sum2;
}
public static void main(String[] args) {
for (int n = 1; n <= 100; n++) {
assert verifyFormula(n) : "Failed at n=" + n;
}
System.out.println("验证通过");
}
}
四、算法面试中的数学应用¶
4.1 时间复杂度分析(5W1H)¶
Why - 为什么要分析复杂度?
- 选择最优算法
- 向面试官展示专业能力
- 避免超时
What - 常见复杂度有哪些?
O(1):常数时间
O(log n):对数时间(二分查找、平衡树)
O(n):线性时间(遍历、双指针)
O(n log n):线性对数(快速排序、归并排序)
O(n²):平方时间(双层循环、冒泡排序)
O(2ⁿ):指数时间(暴力回溯)
O(n!):阶乘时间(全排列)
When - 什么时候分析?
- 写代码前先分析
- 提交前检查是否超时
- 面试时主动说明
Where - 在哪些场景分析?
LeetCode 提交:
- 数据规模 10⁵ → 必须 O(n log n) 或 O(n)
- 数据规模 10³ → O(n²) 可以接受
- 数据规模 20 → O(2ⁿ) 可以接受
Who - 谁会要求你分析?
面试官必问:
- "时间复杂度是多少?"
- "空间复杂度是多少?"
- "能不能优化?"
How - 怎么分析?
// 示例:分析代码复杂度
// O(n) - 单层循环
public void linear(int n) {
for (int i = 0; i < n; i++) {
// O(1)
}
}
// O(n²) - 双层循环
public void quadratic(int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// O(1)
}
}
}
// O(log n) - 每次减半
public void logarithmic(int n) {
for (int i = n; i > 0; i /= 2) {
// O(1)
}
}
// O(n log n) - 外层 n,内层 log n
public void nlogn(int n) {
for (int i = 0; i < n; i++) {
for (int j = n; j > 0; j /= 2) {
// O(1)
}
}
}
五、学习建议¶
5.1 复习优先级(5W1H)¶
Why - 为什么按优先级复习?
时间有限,必须聚焦高频考点。
面试不会考所有知识点。
What - 优先级如何划分?
P0(必须掌握):
- 对数/指数运算(复杂度分析)
- 排列组合(回溯/DP)
- 基础概率(面试概率题)
P1(建议掌握):
- 导数基础(最优化理解)
- 数列求和(复杂度推导)
- 向量的点积/叉积(相似度)
P2(了解即可):
- 矩阵运算(高级算法)
- 贝叶斯定理(机器学习)
- 微积分(数值计算)
When - 什么时候复习?
- 每天 1-2 小时
- 刷 LeetCode 前复习
- 面试前一周突击
Where - 在哪练习?
- LeetCode 数学相关标签
- 牛客网概率题
- 自测题目
Who - 谁能帮你?
- AI 助手讲解知识点
- 刷题社区讨论
- 面试官反馈
How - 怎么高效复习?
1. 理解公式来源(为什么这样设计)
2. 配合代码实现(用 Java 写出来)
3. 找 LeetCode 题目练习(至少 3 题)
4. 面试时能解释(能说清楚推导过程)
六、快速查表¶
6.1 常用公式¶
| 名称 | 公式 | 应用场景 |
|---|---|---|
| 等差求和 | Sₙ = n(a₁+aₙ)/2 | 前缀和、O(1) 计算 |
| 等比求和 | Sₙ = a₁(1-qⁿ)/(1-q) | 分治复杂度 |
| 排列数 | P(n,m) = n!/(n-m)! | 回溯、全排列 |
| 组合数 | C(n,m) = n!/[m!(n-m)!] | 子集、DP |
| 二项式 | (a+b)ⁿ = Σ C(n,k)aⁿ⁻ᵏbᵏ | 概率、展开 |
| 贝叶斯 | P(A|B) = P(B|A)P(A)/P(B) | 推断、分类 |
6.2 复杂度常用级数¶
| 级数 | 和 | 复杂度 | 典型场景 |
|---|---|---|---|
| Σ i (1..n) | n(n+1)/2 | O(n²) | 双层循环 |
| Σ log i (1..n) | log(n!) | O(n log n) | 归并排序 |
| Σ 2ⁱ (0..n) | 2ⁿ⁺¹-1 | O(2ⁿ) | 暴力回溯 |
| Σ 1/i (1..n) | ≈ ln n | O(log n) | 调和级数 |
| Σ i² (1..n) | n(n+1)(2n+1)/6 | O(n³) | 三层循环 |
相关文档: - 数据结构与算法 7 天冲刺 - ClickHouse 深度解析 - 算法复杂度分析
二、初中数学核心¶
2.1 代数基础¶
方程与不等式¶
一元二次方程:ax² + bx + c = 0
求根公式:x = (-b ± √(b² - 4ac)) / 2a
判别式:Δ = b² - 4ac
- Δ > 0:两个不等实根
- Δ = 0:两个相等实根
- Δ < 0:无实根
韦达定理(Vieta's Formulas):
x₁ + x₂ = -b/a
x₁ × x₂ = c/a
应用:LeetCode 中涉及数学推导的题目
因式分解¶
常用公式:
1. 平方差:a² - b² = (a+b)(a-b)
2. 完全平方:a² ± 2ab + b² = (a±b)²
3. 立方和/差:a³ ± b³ = (a±b)(a² ∓ ab + b²)
4. 十字相乘法:ax² + bx + c = (px+q)(rx+s)
应用:优化计算、减少时间复杂度
2.2 函数基础¶
一次函数与二次函数¶
一次函数:y = kx + b
- 斜率 k = (y₂-y₁)/(x₂-x₁)
- 截距 b(与 y 轴交点)
二次函数:y = ax² + bx + c
- 顶点:(-b/2a, (4ac-b²)/4a)
- 对称轴:x = -b/2a
- 开口方向:a>0 向上,a<0 向下
应用:算法中的最优化问题、二分查找的单调性判断
2.3 几何基础¶
平面几何¶
三角形:
- 面积:S = ½ × 底 × 高
- 勾股定理:a² + b² = c²(直角三角形)
- 正弦定理:a/sinA = b/sinB = c/sinC = 2R
- 余弦定理:c² = a² + b² - 2ab·cosC
四边形:
- 矩形面积:S = 长 × 宽
- 平行四边形:S = 底 × 高
- 梯形:S = ½ × (上底+下底) × 高
圆:
- 周长:C = 2πr
- 面积:S = πr²
- 弧长:l = rθ(θ 为弧度)
应用:计算几何题目、图形渲染、碰撞检测
2.4 统计与概率¶
基础统计¶
集中趋势:
- 平均数:x̄ = Σxᵢ/n
- 中位数:排序后中间的数
- 众数:出现次数最多的数
离散程度:
- 方差:σ² = Σ(xᵢ-x̄)²/n
- 标准差:σ = √σ²
- 极差:max - min
应用:数据分析、A/B 测试、质量监控
基础概率¶
概率定义:P(A) = 事件 A 发生的次数 / 总试验次数
基本公式:
1. 互斥事件:P(A∪B) = P(A) + P(B)
2. 独立事件:P(A∩B) = P(A) × P(B)
3. 条件概率:P(A|B) = P(A∩B) / P(B)
4. 全概率公式:P(B) = Σ P(B|Aᵢ)·P(Aᵢ)
应用:随机算法、蒙特卡洛方法、概率题面试
三、高中数学核心¶
3.1 函数与导数¶
指数/对数完整版见上文 §3.1 指数函数与对数函数(重点专题)(含二分、n log n 推导、误区、Java)。
常见函数(速查)¶
指数 y=aˣ:O(2ⁿ) 爆炸;对数 y=logₐx:O(log n) 减半
顺序:O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(2ⁿ)
幂函数 y=xⁿ:O(n²)、O(n³)
导数基础¶
导数定义:f'(x) = lim(h→0) [f(x+h) - f(x)] / h
常用导数:
- (xⁿ)' = n·xⁿ⁻¹
- (sin x)' = cos x
- (cos x)' = -sin x
- (eˣ)' = eˣ
- (ln x)' = 1/x
导数应用:
1. 判断单调性:f'(x)>0 递增,f'(x)<0 递减
2. 求极值:f'(x)=0 的点是驻点
3. 最优化问题:梯度下降的基础
应用:机器学习、最优化算法、数值计算
3.2 数列与级数¶
等差数列¶
通项公式:aₙ = a₁ + (n-1)d
前 n 项和:Sₙ = n(a₁ + aₙ)/2 = n·a₁ + n(n-1)d/2
性质:
- 任意两项之差为常数 d
- 求和时间复杂度 O(1)
应用:前缀和、滑动窗口、批量计算
等比数列¶
通项公式:aₙ = a₁·qⁿ⁻¹
前 n 项和:Sₙ = a₁(1-qⁿ)/(1-q) (q≠1)
无穷等比级数(|q|<1):
S = a₁/(1-q)
应用:分治算法复杂度 T(n) = 2T(n/2) + O(n) = O(n log n)
常见级数¶
1. 调和级数:1 + 1/2 + 1/3 + ... + 1/n ≈ ln n + γ
应用:快速排序平均复杂度分析
2. 等差级数:1 + 2 + 3 + ... + n = n(n+1)/2
应用:双层循环时间复杂度 O(n²)
3. 几何级数:1 + 2 + 4 + ... + 2ⁿ = 2ⁿ⁺¹ - 1
应用:二叉树节点数、分治算法
3.3 排列组合¶
排列(Permutation)¶
定义:从 n 个不同元素中取出 m 个元素的有序排列
公式:P(n,m) = n!/(n-m)!
全排列:P(n,n) = n!
应用:回溯算法、排列组合题目
组合(Combination)¶
定义:从 n 个不同元素中取出 m 个元素的无序组合
公式:C(n,m) = n!/[m!(n-m)!]
性质:
1. C(n,m) = C(n,n-m)
2. C(n,m) = C(n-1,m-1) + C(n-1,m) (杨辉三角)
应用:子集问题、组合问题、动态规划状态转移
二项式定理¶
(a+b)ⁿ = Σ C(n,k)·aⁿ⁻ᵏ·bᵏ (k=0 to n)
应用:概率计算、多项式展开
3.4 概率论进阶¶
随机变量¶
离散型随机变量:
- 概率分布:P(X=xᵢ) = pᵢ
- 期望:E(X) = Σ xᵢ·pᵢ
- 方差:D(X) = E[(X-E(X))²] = E(X²) - [E(X)]²
连续型随机变量:
- 概率密度函数 f(x)
- 期望:E(X) = ∫ x·f(x)dx
- 方差:D(X) = ∫ (x-E(X))²·f(x)dx
应用:期望 DP、随机算法分析
常见分布¶
二项分布 B(n,p):
- n 次独立重复试验,每次成功概率 p
- P(X=k) = C(n,k)·pᵏ·(1-p)ⁿ⁻ᵏ
- E(X) = np, D(X) = np(1-p)
泊松分布 P(λ):
- 单位时间内事件发生次数
- P(X=k) = λᵏ·e⁻λ/k!
- E(X) = λ, D(X) = λ
正态分布 N(μ,σ²):
- 钟形曲线,对称分布
- 68-95-99.7 规则
- 应用:A/B 测试、统计推断
应用:概率题、蒙特卡洛、统计学习
条件概率与贝叶斯¶
条件概率:P(A|B) = P(A∩B) / P(B)
贝叶斯定理:
P(A|B) = P(B|A)·P(A) / P(B)
全概率公式:
P(B) = Σ P(B|Aᵢ)·P(Aᵢ)
应用:贝叶斯分类器、推荐系统、概率推断
3.5 向量与矩阵¶
向量基础¶
向量:有大小和方向的量
运算:
- 加法:a + b = (a₁+b₁, a₂+b₂, ...)
- 数乘:k·a = (ka₁, ka₂, ...)
- 点积:a·b = Σ aᵢbᵢ = |a||b|cosθ
- 叉积:a×b(三维,结果是向量)
模长:|a| = √(a₁² + a₂² + ...)
应用:机器学习特征向量、相似度计算、图形学
矩阵基础¶
矩阵乘法:C = AB
- C[i][j] = Σ A[i][k]·B[k][j]
矩阵性质:
- (AB)ᵀ = BᵀAᵀ
- (AB)⁻¹ = B⁻¹A⁻¹
应用:动态规划优化、图论、线性方程组
3.6 数学归纳法¶
证明步骤:
1. 基础步骤:验证 n=1 时命题成立
2. 归纳步骤:假设 n=k 时成立,证明 n=k+1 时也成立
应用:算法正确性证明、递推关系证明
例子:证明 1+2+...+n = n(n+1)/2
- n=1: 1 = 1×2/2 ✓
- 假设 n=k: 1+2+...+k = k(k+1)/2
- 证明 n=k+1:
1+2+...+k+(k+1) = k(k+1)/2 + (k+1)
= (k+1)(k+2)/2 ✓
四、算法面试中的数学应用¶
4.1 时间复杂度分析¶
O(1):常数时间
O(log n):对数时间(二分查找、平衡树)
O(n):线性时间(遍历、双指针)
O(n log n):线性对数(快速排序、归并排序)
O(n²):平方时间(双层循环、冒泡排序)
O(2ⁿ):指数时间(暴力回溯)
O(n!):阶乘时间(全排列)
级数求和:
- Σ i (i=1 to n) = O(n²)
- Σ log i (i=1 to n) = O(n log n)
- Σ 2ⁱ (i=0 to n) = O(2ⁿ)
4.2 空间复杂度¶
O(1):常数空间(原地算法)
O(n):线性空间(数组、哈希表)
O(log n):对数空间(递归栈、二分)
O(n²):平方空间(二维数组、邻接矩阵)
4.3 概率算法¶
蒙特卡洛方法:
- 随机采样估计结果
- 精度与采样次数成正比
- 应用:π 计算、积分估计
随机化算法:
- 快速排序随机 pivot
- 哈希表随机哈希函数
- 应用:避免最坏情况
五、常见数学面试题型¶
5.1 数论基础¶
1. 最大公约数(GCD)
辗转相除法:gcd(a,b) = gcd(b, a%b)
2. 最小公倍数(LCM)
lcm(a,b) = a×b / gcd(a,b)
3. 质数判断
试除法:O(√n)
埃拉托斯特尼筛法:O(n log log n)
4. 模运算
(a+b)%m = (a%m + b%m)%m
(a×b)%m = ((a%m)×(b%m))%m
aⁿ%m = (a%m)ⁿ%m(快速幂)
5.2 组合数学题¶
典型题目:
1. 排列组合:C(n,m) 计算
2. 杨辉三角:动态规划生成
3. 卡特兰数:Cₙ = C(2n,n)/(n+1)
应用:合法括号序列、二叉树计数
公式记忆:
- C(n,0) = C(n,n) = 1
- C(n,m) = C(n-1,m-1) + C(n-1,m)
5.3 概率题¶
1. 掷骰子问题
- 期望 E = Σ xᵢ·pᵢ
- 方差 D = E(X²) - [E(X)]²
2. 抽奖问题
- 超几何分布
- 二项分布近似
3. 生日悖论
- n 人中至少两人生日相同的概率
- n=23 时概率 > 50%
六、学习建议¶
6.1 复习优先级¶
P0(必须掌握):
- 对数/指数运算(复杂度分析)
- 排列组合(回溯/DP)
- 基础概率(面试概率题)
P1(建议掌握):
- 导数基础(最优化理解)
- 数列求和(复杂度推导)
- 向量的点积/叉积(相似度)
P2(了解即可):
- 矩阵运算(高级算法)
- 贝叶斯定理(机器学习)
- 微积分(数值计算)
6.2 学习资源¶
在线资源:
- 3Blue1Brown(YouTube):直观理解线性代数
- 可汗学院:系统复习初高中数学
- B 站:宋浩高等数学(系统性强)
实践方法:
1. 每学一个公式,找 1-2 道 LeetCode 应用
2. 复杂度分析必须熟练掌握
3. 概率题多做练习(面试常考)
七、快速查表¶
7.1 常用公式¶
| 名称 | 公式 | 应用 |
|---|---|---|
| 等差求和 | Sₙ = n(a₁+aₙ)/2 | 前缀和、O(1) 计算 |
| 等比求和 | Sₙ = a₁(1-qⁿ)/(1-q) | 分治复杂度 |
| 排列数 | P(n,m) = n!/(n-m)! | 回溯、全排列 |
| 组合数 | C(n,m) = n!/[m!(n-m)!] | 子集、DP |
| 二项式 | (a+b)ⁿ = Σ C(n,k)aⁿ⁻ᵏbᵏ | 概率、展开 |
| 贝叶斯 | P(A|B) = P(B|A)P(A)/P(B) | 推断、分类 |
7.2 复杂度常用级数¶
| 级数 | 和 | 复杂度 |
|---|---|---|
| Σ i (1..n) | n(n+1)/2 | O(n²) |
| Σ log i (1..n) | log(n!) | O(n log n) |
| Σ 2ⁱ (0..n) | 2ⁿ⁺¹-1 | O(2ⁿ) |
| Σ 1/i (1..n) | ≈ ln n | O(log n) |
| Σ i² (1..n) | n(n+1)(2n+1)/6 | O(n³) |
相关文档: - 数据结构与算法 7 天冲刺 - ClickHouse 深度解析 - 算法复杂度分析