汉诺塔问题是一个经典的递归问题,大意是:有A, B, C三根柱子,A柱上有n个盘子,小的在上,大的在下,现在要在B柱的帮助下将A柱上的所有盘子移动到C柱上,而且要求每次只能移动一个,并且任何时候小的盘子只能在大的盘子上面。
利用递归逐步分解问题的思想可以轻松解决这道题。首先考虑只有一个圆盘(n=0)的情况,之间从A移动到C即可;对于n个圆盘的情况,可以分解为3步:首先把上层 n-1 个圆盘移到B柱,然后把A柱上的1个圆盘移到C柱,最后把B柱上的 n-1 个圆盘移到C柱,完成移动。所以问题就变成了 n-1 个柱子移动的问题,以此类推,直到回到最初的移动一个圆盘的时候。Python实现的代码如下:
def move(n, a, b, c): if n == 1: print(a, ' --> ', c) return move(n-1, a, c, b) move(1, a, b, c) move(n-1, b, a, c) return #结果如下: >>> move(3, 'A', 'B', 'C') A --> C A --> B C --> B A --> C B --> A B --> C A --> C
根据上述分析,第n个盘子需要把其上n-1个移走,然后底座1个移去目的地,最后把n-1个移过来,可以得出移n个盘子的所需的次数 f(n )= f(n-1)* 2 + 1,解出来后 f(n)= 2^n - 1。古老传说中大梵天让婆罗门移动上有64片黄金圆盘的汉诺塔,计算一下,需要移动 2^64 - 1 次,就算一次一秒,完成也需要约5846亿年,可怕!
总结:我们可以看到,在解决这个问题的时候,如果纠结于每一个圆盘的移动,就会很复杂,但如果能够站在高处,不拘于细节而是把整个过程分解为几个大的部分,就能逐渐转化为更简单的问题。在思考递归的时候,可以将其当作一个黑盒来看待,而不必进入递归内部,否则容易越陷越深。