1. 汉诺塔问题
汉诺塔是理解递归最经典的案例。将 n 个盘子从 A 柱移到 C 柱(B 为辅助),核心在于把大问题拆解成两个规模相同的子问题。
具体步骤如下:
- 先把上面 n-1 个盘子从 A 移到 B(此时 C 作为辅助)。
- 将最底下的最大盘子直接从 A 移到 C。
- 再把那 n-1 个盘子从 B 移到 C(此时 A 作为辅助)。
每一层递归只负责当前盘子的移动逻辑,当 n=1 时直接移动即可。这种自顶向下拆分、自底向上合并的过程,正是递归的精髓。
实现代码参考:
class Solution {
public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {
movePlant(A, B, C, A.size());
}
private void movePlant(List<Integer> start, List<Integer> temp, List<Integer> target, int size) {
if (size == 1) {
target.add(start.remove(start.size() - 1));
return;
}
// a 借助 c 将 n-1 个盘子放到 b
movePlant(start, target, temp, size - 1);
// a 剩下的一个盘子 放到 c
target.add(start.remove(start.size() - 1));
// b 借助 a 将 n-1 个盘子放到 c
movePlant(temp, start, target, size - 1);
}
}
2. 合并两个有序链表
合并链表看似简单,但用递归处理能极大简化指针操作。思路是每次比较两个链表当前的头节点,选小的那个作为新链表的头,然后让它的 next 指向剩余部分的递归结果。
关键点在于递归出口:只要有一个链表为空,直接返回另一个链表即可。空指针在 Java 中会被自然处理,无需额外判断。


