递归算法核心原理与 LeetCode 实战解析
递归的核心概念
在计算机算法学习中,递归是一个绕不开的概念。它的本质是通过函数自我调用来解决复杂问题。虽然代码结构往往简洁,但设计思路需要清晰的逻辑支撑。
设计一个有效的递归通常遵循以下步骤:
- 确定子问题:确认原问题可以分解为多个重复的子问题,且子问题的解决方法与原问题一致。
- 抽象共同点:从宏观角度找出这些子问题的共性。
- 定义函数头:明确函数的职责,即它具体解决什么问题。
- 设定终止条件:这是递归的出口,必须确保在执行过程中一定会触发,避免死循环。
初学者常觉得递归像'左脚踩右脚上天',略显抽象。其实,递归就是发现大问题能拆解成小问题,小问题又能继续拆解,直到达到某个基准情况。我们设计的算法正是模拟这种不断分化的过程。
经典案例实战
汉诺塔问题
LeetCode 面试题 08.06. 汉诺塔问题 是理解递归的经典场景。目标是将 A 柱上的盘子借助 B 柱移动到 C 柱。

观察不同数量的盘子:
- 1 个盘子:直接从 A 移到 C。
- 2 个盘子:先将上面的盘子移到 B,再将最大的移到 C,最后将 B 上的移到 C。
- n 个盘子:逻辑相同,先借助 C 将 n-1 个盘子移到 B,再将第 n 个移到 C,最后将 B 上的 n-1 个移到 C。
这里的递归出口是当盘子数量为 1 时,直接移动并返回。
实现逻辑如下,dfs 函数表示借助 Y 将 X 上的盘子移到 Z:
class Solution {
public:
void dfs(vector<int>& x, vector<int>& y, vector<int>& z, int n) {
if (n == 1) {
z.push_back(x.back());
x.pop_back();
return;
}
dfs(x, z, y, n - 1);
z.push_back(x.back());
x.pop_back();
(y, x, z, n - );
}
{
(a, b, c, a.());
}
};





