1. 问题来源:
汉诺塔(河内塔)问题是印度的一个古老的传说。
法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
后来,这个传说就演变为汉诺塔游戏,玩法如下:
(1). 有三根杆子A,B,C。A杆上有若干碟子
(2). 每次移动一块碟子,小的只能叠在大的上面
(3). 把所有碟子从A杆全部移到C杆上
2. 解题思路:
题中只给了三座塔,我们利用B塔将圆盘全部移动到在C塔。
为了将N个盘子从A移动到C,需要先将第N个盘子上面的N-1个盘子移动到B上,这样才能将第N个盘子移动到C上。
同理,为了将第N-1个盘子从B移动到C上,需要将N-2个盘子移动到A上,这样才能将第N-1个盘子移动到C上。
通过递归就可以实现汉诺塔问题的求解。
3. 源代码:
public class Hanoi { private static void move(int level, char from, char inter, char to) {
if (level == 1) {
System.out.println(level + ":" + from + "->" + to);
} else {
move(level - 1, from, to, inter);
System.out.println(level + ":" + from + "->" + to);
move(level - 1, inter, from, to);
}
} public static void move(int level) {
move(level, 'A', 'B', 'C');
}
}
测试代码:
public class Main {
public static void main(String[] args) {
int nDisks = 3;
Hanoi.move(nDisks);
}
}
测试结果:
1:A->C
2:A->B
1:C->B
3:A->C
1:B->A
2:B->C
1:A->C
当然,在这里圆盘的个数nDisks可以通过java.util.Scanner从控制台进行读入:
import java.util.Scanner; public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int nDisks = in.nextInt();
in.close();
Hanoi.move(nDisks);
}
}
汉诺塔问题的时间复杂度为O(2^n)