递归是程序员写算法题中,必须要理解的。有时拿不准结构是否正确,可以debug一下。以下例题都是和递归有关。
汉诺塔游戏
示例代码如下:
class Solution {
public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {
move(A.size(), A, B, C);
}
void move(int n, List<Integer> A, List<Integer> B, List<Integer> C) {
if (n == 1) {
//只有一个时,直接从a放到C
C.add(A.remove(A.size() - 1));
} else {
//先从a到b上放一个
B.add(A.remove(A.size() - 1));
//再把剩下的n-1个从a利用b放到C
move(n - 1, A, B, C); // 一处递归即可
//再把最开始的那个从b放到C
C.add(B.remove(B.size() - 1));
}
}
}
思路如下:
首先判断终止条件,等于1时直接从A到C,其余情况,先从a到b放一个,把A的n-1个从A通过B到C,再把最开始的那个从b到c。
还有一种递归方式:
把n-1个从A到b,再把1个从a到c,最后把n-1个从b到c。这种方式简单易懂,使用了2次递归,可惜超时。代码如下:
public static void hanoi(int n, List<Integer> a, List<Integer> b, List<Integer> c) {
if (a.size() == 1) {
//如果只有一个,直接从A移动到C即可
c.add(a.remove(a.size() - 1));
} else {
//表示先把n-1个圆盘成功从A移动到B
hanoi(n - 1, a, c, b);
//把第n个圆盘从A移动到C
// System.out.println("从" + A + "移动到" + C);
c.add(a.remove(a.size() - 1));
//表示把n-1个圆盘再成功从B移动到C
hanoi(n - 1, b, a, c);
}
}
仔细揣摩递归的特点,想想这题为什么这么写。