首先,先放代码,讲解以及注释将会在后文里单独写出来
public class hnt {
public static void main(String[] args) {
hnts("a","b","c",3);
}
public static void hnts(String from,String temp,String to,int n){
if(n==1){
System.out.println(from+"------>"+to);
}else{
hnts(from,to,temp,n-1);
hnts(from,temp,to,1);
hnts(temp,from,to,n-1);
}
}
}
原始问题描述(来源百度百科)
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根柱子(编号A、B、C),在A杆至上而下、由大到小按顺序放置64个金盘(如下图)。游戏的目标:把A杆上的金盘全部移动到C杆子上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
解题思路
首先,我们先统一一下环境设想,当一个汉诺塔摆在我们面前的时候,我们认定某块圆盘是(任何柱)从上往下数第几块的时候,我们就给这块圆盘设定一个编号为n
然后给三个柱子设定一个以圆盘为视角的命名,分别是盘子目前所在的地方“from”,盘子想要到达的地方“to”,剩余的另外一个可以作为临时落脚点的柱子“temp”
则概括汉诺塔规律一共分为四步:
一:当这块圆盘(n)是在最上层的时候,即n==1的时候,则这个盘子就可以直接从from移动到to
System.out.println(from+"------>"+to);
二:当这块圆盘(n)不是在最上层的时候,即它上边还有圆盘的时候,我们需要把它上边的那一块圆盘(n-1)先移动到temp上
hnts(from,to,temp,n-1);
三:当圆盘(n-1)移动到temp之后,这时,圆盘n就会变成n-(n-1)=1,所以此时的圆盘n(现在是1)就可以直接移动到to
hnts(from,temp,to,1);
四:当圆盘n(1),移动到to之后,我们就需要把放在temp上的(n-1)移动到to上
hnts(temp,from,to,n-1);
总结以及举一反三
这四步其实是我们根据一定的经验和尝试总结的规律。
这道题的思考路线可以总结为一下部分,总结思考路线可以用以帮助我们以后面临同样的问题时,举一反三:
首先,当我们看到这道题时,我们可以先简单带入1,2个盘子进行尝试,当我们尝试有3个盘子的时候,我们就应该思考一下,这是一道可以用什么方法解决的问题,经过1,2,3个盘子的尝试,我们可以大致发现,这个移动是有一点规律的,好,那么我们就基本可以猜到可以用循环或者递归试试了,但是显然使用循环的话,对盘子的循环跳转控制太弱,所以可以选择使用递归,如果不行就再尝试使用循环。
既然选择使用递归,那么我们就开始思考,如何去找到这个规律。
一般递归解决问题的概念大致可以理解为冰箱放大象:打开冰箱门,把大象塞进去,关上冰箱门。 但是其中过程是怎么塞进去的,怎么关上门的,我们不用过多思考,我们只需要给它一个开始(传参),和一个结束(出口)。所以此时我们就可以找到如上文所述的四个解决步骤。利用这四个步骤我们就可以找到问题的解决方案。