递归是用函数自身定义问题的编程思想,适用于阶乘、斐波那契、树形结构等自相似场景;关键在于明确边界、避免重复计算与栈溢出,结合记忆化与结构化设计实现优雅解法。

递归是一种用函数自身来定义或解决问题的编程思想,它天然契合阶乘、斐波那契数列和树形结构这类具有自相似性的场景。写得清楚、边界明确、不爆栈、不重复计算,就是“优雅”的关键。
阶乘:抓住“n! = n × (n−1)!”这个核心关系
阶乘的数学定义本身就是递归的:0! = 1(这是终止条件),n! = n × (n−1)!(这是递推关系)。代码只需忠实还原这两点:
- 明确写死 base case:当 n == 0 或 n == 1 时,直接返回 1
- 递归调用只做一件事:返回 n * factorial(n - 1),不掺杂打印、计数等额外逻辑
- 避免对负数调用——加个输入校验,比如抛出 ValueError 或直接返回 None
斐波那契:别裸写递归,用记忆化剪掉重复分支
朴素递归(f(n) = f(n−1) + f(n−2))时间复杂度是指数级,因为大量子问题被反复计算。优雅解法是在保持递归结构的同时引入缓存:
- 用字典或 lru_cache 装已算过的 f(k) 值,下次直接取,不再递归
- Python 中最简方式是加一行 @lru_cache(maxsize=None) 装饰器
- 手动实现时,在函数外建 cache 字典,每次先查再算再存,base case 仍是 n == 0 → 0,n == 1 → 1
树形查找:把“查左子树”和“查右子树”当作两个独立子任务
二叉树天然递归:一棵树由根节点、左子树、右子树构成。查找某个值,逻辑非常清晰:
- 如果当前节点为空,返回 False
- 如果当前节点值等于目标,返回 True
- 否则,递归查左子树 或 递归查右子树,用 or 连接结果
- 想返回路径?让递归函数返回节点引用或路径列表,遇到匹配就层层往上拼接,没匹配就返回 None 或空列表
递归不是炫技,而是让代码结构与问题结构对齐。只要 base case 稳、递推逻辑纯、资源控制住(比如栈深、缓存大小),它就是最直观也最可读的解法。











