前言:
这样一个数列:0、1、1、2、3、5、8、13、21、……在数学上,斐波纳契数列以如下被以递归的方法定义:
,
,
。用文字来说,就是斐波那契数列由 0 和 1 开始,之后的斐波那契数列系数就由之前的两个数字相加。
问题:
一个台阶有n级,人可以走1级台阶或者走2级台阶。问,一共有多少种走法?例子:比如有3级台阶。第一种:可以先走1级,再走2级;第二种:可以先走1级,再走1级,再走1级;第三种:可以先走2级,再走1级。这样,一共有3种走法。
解答:
这是典型的斐波纳契数列问题,可以知道,当台阶只有1级时,有1种走法;台阶2级,有2种走法;台阶3级,有3种走法;台阶4级,有5种走法......,根据这个规律,可以发现这个数列的顺序是:1,2,3,5,8,13,21,34.......,符合
这个规律(虽然不是从0开始)。
方法1:递归
# -*-encoding:utf-8 -*-
def recursion(n):
assert type(n) == int
result = 0
if n == 0:
return 0
elif n == 1:
return 1
elif n == 2:
return 2
else:
return recursion(n-1) + recursion(n-2)
r = recursion(4)
print(r) # 5
方法2:非递归
# -*-encoding:utf-8 -*-
'''
因为f(n)=f(n-2)+f(n-1),one表示f(n-2),two表示f(n-1)。
可以发现,每循环一次要做三件事,
1,更新result的值 (result=one+two:结果等于前面两个的和)
2,更新one的值 (one的值被two覆盖)
3,更新two的值 (two的值被原来的result覆盖)
'''
def no_recursion(n):
assert type(n) == int
result = 0 #最终结果
one = 0 # f(n-2)
two = 1 # f(n-1)
for i in range(0,n):
result = one + two #更新result的值
one = two #更新f(n-2)的值
two = result #更新f(n-1)的值
return result
r = no_recursion(4)
print(r) #5
算法比较:
通过以下两个算法的比较。
1:递归算法比较简单,一下子就知道怎么实现的,但是耗时比较大。
2:非递归算法比较难实现,但是运行速度快,基本没什么耗时。
# -*-encoding:utf-8 -*-
import time
def recursion(x):
assert type(x) == int
result = 0
def step(n):
if n == 0:
return 0
elif n == 1:
return 1
elif n == 2:
return 2
else:
return step(n-1) + step(n-2)
result = step(x)
return result
def no_recursion(x):
assert type(x) == int
result = 0
one = 0
two = 1
for i in range(0,x):
result = one + two
one = two
two = result
return result
t1 = time.time()
r1 = recursion(32)
t2 = time.time()
r2 = no_recursion(32)
t3 = time.time()
time1 = (t2-t1)*1000
time2 = (t3-t2)*1000
print("递归结果:",r1,"递归耗时:",round(time1,2),"ms")
# 递归结果: 3524578 递归耗时: 1710.1 ms
print("非递归结果:",r2,"递归耗时:",round(time2,2),"ms")
# 非递归结果: 3524578 递归耗时: 0.0 ms