斐波那契数(台阶有多少种走法)

前言:

        这样一个数列:0、1、1、2、3、5、8、13、21、……在数学上,斐波纳契数列以如下被以递归的方法定义:\tiny f(0)=0,\tiny f(1)=1 ,\tiny f(n)=f(n-1)+f(n-2) (n>2,n\subset N*)。用文字来说,就是斐波那契数列由 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.......,符合\tiny f(n)=f(n-1)+f(n-2) 这个规律(虽然不是从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

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值