Hi,我是哈缺氧。
汉诺塔作为入门级的递,很好锻炼了大家的思维能力,今天就来聊聊汉诺塔问题。
如图,思考一个问题,如何将 A 柱子的方块移动到 B 柱子(任何时刻下,同一柱子由上到下由小到大)。如果将 A 柱子由上到下编号 1 ~ 3
,我们可以知道,如果要按照要求移动首先需要将 1, 2
移动到 C 柱子上,将 3
移动到 B 柱子上,将 1, 2
移回 B 柱子上,可能你会感到诧异,不过这就是递归。
我们能否得到递推关系,f(n, A, B, C)
= f(n - 1, A, C, B)
+ f(1, A, B, C)
+ f(n - 1, C, B, A)
。
当然 n = 1
时,就是递归结束的条件,接下来我们来代码实现一下。
public static void hanoi(int i, String a, String b, String c) {
if (i == 1) {
System.out.println(i + " : " + a + " -> " + b);
return;
}
hanoi(i - 1, a, c, b);
hanoi(1, a, b, c);
hanoi(i - 1, c, b, a);
}
现在,我们应该就只有一个问题,为什么要在递归函数中条件是 n = 1
打印,从其他地方打印是否可以?
n 其实就是柱子的个数,你想想如果可以一下移动多个柱子,那不直接将 A 柱子移动到 B 柱子不就完事了?
留一个思考题,如果 n 现在不代表个数而是代表当前移动的编号木块,我们该怎么办?
以上就是我对汉诺塔的全部理解,下面附上代码。
代码:
import java.util.ArrayList;
import java.util.Random;
public class Main {
public static void main(String[] args) {
hanoi(3, "A", "B", "C");
}
public static void hanoi(int n, String a, String b, String c) {
if (i == 1) {
System.out.println(a + " -> " + b);
return;
}
hanoi(n - 1, a, c, b);
hanoi(1, a, b, c);
hanoi(n - 1, c, b, a);
}
}
结果:
A -> B
A -> C
B -> C
A -> B
C -> A
C -> B
A -> B
题解
import java.util.ArrayList;
import java.util.Random;
public class Main {
public static void main(String[] args) {
hanoi(3, "A", "B", "C");
}
public static void hanoi(int i, String a, String b, String c) {
if (i == 1) {
System.out.println(i + " : " + a + " -> " + b);
return;
}
hanoi(i - 1, a, c, b);
System.out.println(i + " : " + a + " -> " + b);
hanoi(i - 1, c, b, a);
}
}
结果:
1 : A -> B
2 : A -> C
1 : B -> C
3 : A -> B
1 : C -> A
2 : C -> B
1 : A -> B