递归是一种极为常用的编程思想。比较官方的解释是“可以在函数内部,直接或间接地调用函数自身”,我一般把他称为“一种有技术含量的偷懒算法”。为什么这么说呢?因为递归函数不需要我们对运算过程的每一步的细节了解详细,而只需要我们知道两点:
1. 函数是如何“升级”的。也就是这一步需要解决的问题与其子问题之间的关系
2. 函数到什么位置“触底”,“触底”后返回什么?
看一个具体的例子:计算n!,当然,在数学上是这样计算的:n! = 1 x 2 x 3 x 4 x...x (n - 1) x n。我们可以这样观察:
1. 函数是如何“升级”的。也就是从 (n - 1)! 到 n! 是怎么做的呢: n! = (n - 1)! x n
2. 函数到什么位置“触底”。显然,当 n = 1的时候,返回1
1. 函数是如何“升级”的。也就是这一步需要解决的问题与其子问题之间的关系
2. 函数到什么位置“触底”,“触底”后返回什么?
看一个具体的例子:计算n!,当然,在数学上是这样计算的:n! = 1 x 2 x 3 x 4 x...x (n - 1) x n。我们可以这样观察:
1. 函数是如何“升级”的。也就是从 (n - 1)! 到 n! 是怎么做的呢: n! = (n - 1)! x n
2. 函数到什么位置“触底”。显然,当 n = 1的时候,返回1
def fact(n):
# “触底”条件及反应
if n == 1:
return 1
# “升级”过程
return n * fact(n - 1)
所以,递归思想帮助我们用接近于自然语言的逻辑描述,完成了程序设计,是算法中非常重要的内容。此外,后面我们会接触到的“深度优先搜索”,“动态规划”也都借用了递归的基本原理,只是应用场景更加特殊罢了。
了解了递归,就可以完成斐波那契数列的构造了。斐波那契数列是说这样一个数列:[0, 1, 1, 2, 3, 5......],每个数都是