问题起源:

一个人爬楼梯,一步可以迈一级,二级,如果楼梯有N级,要求编写程序,求总共有多少种走法。

简单的一个递归思想,只要爬到了N-1层,或者爬到N-2层,则认定下一步只有一种走法。所以再去找寻N-1、N-2的前两步。动态规划方程为:f(n) = f(n-1) +f(n-2)

方案1:

def climb_2(n):  # 速度非常慢
if n not in [1, 2]:
return climb_2(n - 1) + climb_2(n - 2)
else:
return n

但是运行下来,会发现,climb_2(3) = 3 这个值早在最开始已经被计算出来了,但是后面的climb_2(4)以及后面所有的递归,都会再去重新计算一下这个取值。当嵌套复杂起来,做了非常多的重复工作,速度很差。

方案2:

dict_t = {1:1, 2:2}
def climb_1(n):
global dict_t
if n not in dict_t.keys():
dict_t[n - 1] = climb_1(n - 1)
dict_t[n - 2] = climb_1(n - 2)
dict_t[n] = dict_t[n - 1] + dict_t[n - 2]
return dict_t[n]
 

这样虽然也是递归嵌套,但是有了全局的dict_t的字典做存储,不会再傻乎乎将climb_2(3) 重新计算,算是一定层面的优化了。但是呢有个缺点:必须依赖函数外的nonlocal或者global变量。

方案3:

@functools.lru_cache(3)
def climb_3(n):
if n not in [1, 2]:
return climb_3(n - 1) + climb_3(n - 2)
else:
return n

此种方案也是最近学习functools才发现的,有个lru_cache 可以缓存函数的返回值,思路也同方案2,但是更加优雅、干练,而且也摆脱了nonlocal变量的依赖。但是这里还有个问题没弄明白。cache的大小为啥3就够快,但是2就不够。此处留个问号?

方案4:

def climb_4(n):
def inner():
(a, b) = (1, 2)
yield a
yield b
while 1:
yield (a + b)
(a, b) = (b, a + b) bo = inner()
for _ in range(n):
s = next(bo)
return s

方案4用到了yield关键词(最近才学明白),也即生成器。yield可以看成是个特殊的return,只是当再次进入这个方法时,会从上会的yield存档处继续。会有变量保存的效果。

受到这层启发后,编写了上面这个方案,n为1,n为2,设了两道关卡,yield出来个a,yield出来个b。。过了1,2后,就进入了死循环阶段。将a + b生成出去,当再次进入函数时,再将a与b重新继续赋值。整体看起来很不错的一种方案。

最新文章

  1. linux 系统、命令、软件
  2. CCPC2016合肥现场赛
  3. 页面动态table动态合并table
  4. TextBoxFor控件的扩展---Bootstrap在mvc上的应用
  5. 【云计算】mesos生态系统
  6. HDU 5013 City Tour
  7. mysql now() sysdate() curdate()区别
  8. javassist动态修改class
  9. URAL - 1736 - Chinese Hockey
  10. Java调用IDL出错处理
  11. jsp页面中某个src,如某个iframe的src,应该填写什么?可以是html、jsp、servlet、action吗?是如何加载的?
  12. 原生Jdbc操作Mysql数据库开发步骤
  13. Linux第一篇【介绍、安装Ubuntu、基本目录结构】
  14. linux 下ab压力测试
  15. LeetCode专题-Python实现之第26题:Remove Duplicates from Sorted Array
  16. 微信小程序云函数Windows下安装wx-server-sdk
  17. 【代码审计】大米CMS_V5.5.3 任意文件读取漏洞分析
  18. vim 常用
  19. neo4j---删除关系和节点
  20. [iOS] UICollectionView初始化滚动到中间的bug

热门文章

  1. JavaEE高级-JPA学习笔记
  2. Nginx和Apache 转发网络问题
  3. 02-第一个Python程序
  4. 2019长安大学ACM校赛网络同步赛C LaTale (树上DP)
  5. 计蒜客 蓝桥模拟 G. 数列求值
  6. Spring Boot jpa Service层实现代码
  7. Arduino-位操作
  8. R语言-三种方法绘制单位圆
  9. JavaScript正则表达式简介(一)
  10. favicon.ico是什么?