Java | 递归解决汉诺塔问题
前言
大家好!本篇文章将介绍经典的汉诺塔(Tower of Hanoi)问题题解,展示代码语言为:Java。
一、汉诺塔简介
汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
二、解题思路
-
很简单!题目只需遵守🧱三个条件:
- 🥇、小圆盘需在大圆盘之上
- 🥈、每次只能移动一个圆盘
-
🥉、最终圆盘需在同一柱子上
那么,该如何进行圆盘的移动呢?化繁为简,我们不妨简单剖析下三个圆盘情况的移动过程🤭(三根柱子暂且命名为A,B,C 默认摆放至C柱)为了方便展示,两步为一个过程直至结束🚄
1、A->C A->B
2、C->B A->C
3、B->A B->C
4、A->C(结束)
通过上述图解我们不难看出,三个圆盘的汉诺塔问题需要移动7次,但总的来说其实可以分为两步(这里我们假设圆盘数为n):第一步是将A柱上的(n-1)个圆盘通过C柱移动至B柱,再将A柱剩余的一个圆盘移动至C柱;第二部则是将B柱上的(n-1)个圆盘通过A柱移动至C柱。这时候我们就可以使用递归的方法来求解,先定义三个位置pos1,pos2,pos3,分别为起始位置,中转位置,最终位置;再定义一个move方法输出移动路径:pos1->pos2,再定义一个hanoi方法递归实现具体的移动步骤。
三、代码实现
代码如下:
class Test {
public static void main(String[] args) {
hanoi(3, 'A', 'B', 'C');
}
public static void move(char pos1, char pos2) {
System.out.print(pos1 + "->" + pos2 + " ");
}
/**
* @param n 盘子数目
* @param pos1 起始位置
* @param pos2 中转位置
* @param pos3 最终位置
**/
public static void hanoi(int n, char pos1, char pos2, char pos3) {
if (n == 1) {//考虑一个圆盘的情况
move(pos1, pos3);
return;
}
hanoi(n - 1, pos1, pos3, pos2);//借助pos3将n-1挪至pos2,使用递归
move(pos1, pos3);
hanoi(n - 1, pos2, pos1, pos3);//借助pos1将圆盘挪至pos3,使用递归
}
}
输出结果:
🔚总结
本题为经典的递归问题,解决该问题的关键是使用递归,将问题分解为更小的子问题,直到达到基本情况(只有一个盘子),然后逐步解决更复杂的问题。