以下按主题分组梳理常见算法与必备知识,便于快速索引与系统复习。

核心概念

公式速查

复杂度定义(渐进符号):

$$ f(n) = O(g(n)) \iff \exists c, n_0 > 0,\ \forall n \ge n_0,\ 0 \le f(n) \le c,g(n) $$

$$ f(n) = \Omega(g(n)) \iff \exists c, n_0 > 0,\ \forall n \ge n_0,\ 0 \le c,g(n) \le f(n) $$

$$ f(n) = \Theta(g(n)) \iff f(n)=O(g(n))\ \text{且}\ f(n)=\Omega(g(n)) $$

分治递推(主定理常见形态):

$$ T(n)=a,T\left(\frac{n}{b}\right)+f(n),\quad a\ge1,\ b>1 $$

摊还分析(动态数组扩容,倍增策略):

$$ \mathrm{总成本}\ \sum_{i=1}^{m} c_i = O(m)\quad\Rightarrow\quad \mathrm{均摊插入} = O(1) $$

哈希负载因子与期望代价(拉链法):

$$ \alpha = \frac{n}{m},\quad E[\text{链长}] = \alpha, $$

$$ E[\text{查找}]\approx O(1+\alpha) $$

生日悖论近似(冲突概率):当哈希空间大小为 $M$,插入 $k$ 个键时,

$$ P(\text{至少一次冲突}) \approx 1 - e^{-\frac{k(k-1)}{2M}} $$

数据结构

线性结构:数组 vs 链表

数组强调连续内存与随机访问;链表强调节点插删灵活性。

D2 Diagram
qtopie.github.io

栈与队列:同样是线性容器,不同是约束

D2 Diagram
qtopie.github.io

哈希结构:冲突处理思想

冲突并不罕见,关键是冲突后如何组织数据。

D2 Diagram
qtopie.github.io

树与堆:层级结构与局部有序

BST 关注“搜索顺序”,堆关注“堆序性质”。

D2 Diagram
qtopie.github.io

并查集:合并集合 + 路径压缩

并查集维护“元素属于哪个连通分量”。

D2 Diagram
qtopie.github.io

算法范式

图论

图的表示方式:邻接矩阵(Adjacency Matrix)和邻接表(Adjacency List)。

环检测

图类型方法核心逻辑
有向图Kahn 算法(入度)反复剔除入度为 0 的节点,若剩余节点则存在环
有向图DFS 三色染色白→灰→黑,DFS 中遇到灰色节点即判定有环
无向图度数剪枝(剥洋葱)反复剔除度数 ≤ 1 的节点,剩余度数 ≥ 2 的节点组成环
无向图并查集遍历边 (u, v),若 u, v 已在同一集合则闭合有环

割点与桥

割点(Cut Vertex / Articulation Point)和桥(Bridge / Cut Edge)衡量无向图的连通脆弱性。

概念定义比喻
割点移除后图分裂交通核心枢纽瘫痪导致断联
移除后图分裂独木桥一断彻底隔绝

核心规律

Tarjan 算法判定(DFS + dfn/low)

类型判定条件直觉
割点low[v] >= dfn[u]子节点最多绕回 u 自身,断开 u 后子树孤立
low[v] > dfn[u]子节点连 u 都绕不回来,断边即失联

注:若 u 是 DFS 根节点,割点判定改为「有 ≥ 2 个独立子节点」。

应用场景: 网络容灾(单点故障检测)、社交网络分析(连接不同圈子的关键人物)。

字符串

数论与计算几何

DP 优化(进阶)

实用模式与选型

解题

判断一个问题该用什么算法,关键不是“背模板”,而是先做特征识别:从题目目标、数据范围、结构信号三条线索快速缩小候选算法。

看问法:题目到底要什么

题目目标通常直接对应算法类别:

题目目标对应算法信号常用算法/数据结构
最短路径/最少步数图论或层级遍历BFS(广度优先)、Dijkstra
所有组合/所有排列搜索全部可能性回溯(Backtracking)
最大/最小、最多/最少最优子结构动态规划(DP)、贪心
是否包含/是否存在查找与集合哈希表、二分查找
区间求和/区间更新数据维护前缀和、线段树、树状数组

看规模:先用复杂度反推算法

根据输入规模 $n$ 先估算可接受复杂度,再选解法:

看信号:常见题型触发器

DP 识别:两个硬条件

如果怀疑是 DP,至少检查:

从套路到直觉

“信号触发器”是指南针,但高难题往往是多算法组合:

这套方法最大的价值,是快速排除错误方向

实战流程(新题通用)

算法题与工程问题

现实问题通常先“摸索定义”,再“建模求解”,和算法题的路径不同:

维度算法题(练习)现实问题(工程)
条件条件完整明确条件可能缺失且有噪声
目标单一目标,偏最优解多目标权衡(性能/成本/维护性)
过程识别模型 -> 实现代码定义问题 -> 建立模型 -> 迭代优化

为什么还要练算法题:

学习路径建议

数据结构建议顺序:

算法专题建议顺序:

最后,刷题一定配合独立思考:先记录自己的尝试和卡点,再看题解反推思维误区。长期看,错误复盘比单纯刷题更能提升上限。

参考