爬楼梯问题,yield学习总结
问题起源:
一个人爬楼梯,一步可以迈一级,二级,如果楼梯有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重新继续赋值。整体看起来很不错的一种方案。
爬楼梯问题,yield学习总结的更多相关文章
- LeetCode初级算法--动态规划01:爬楼梯
LeetCode初级算法--动态规划01:爬楼梯 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...
- Jarvis OJ - 爬楼梯 -Writeup
Jarvis OJ - 爬楼梯 -Writeup 本来是想逆一下算法的,后来在学长的指导下发现可以直接修改关键函数,这个题做完有种四两拨千斤的感觉,记录在这里 转载请标明出处:http://www.c ...
- lintcode: 爬楼梯
题目: 爬楼梯 假设你正在爬楼梯,需要n步你才能到达顶部.但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部? 样例 比如n=3,中不同的方法 返回 3 解题: 动态规划题目,同时还是有顺序 ...
- 爬楼梯问题-斐波那契序列的应用.md
N 阶楼梯,一次可以爬1.2.3...n步,求爬楼梯的种类数 /** * 斐波那契序列 */ public class ClimbingStairs { // Sol 1: 递归 // 递归 公式:F ...
- 2017广东工业大学程序设竞赛C题爬楼梯
Description 小时候,我只能一阶一阶得爬楼梯, 后来,我除了能一次爬一阶,还可以一次爬两阶, 到现在,我最多一次可以爬三阶. 那么现在问题来了,我想爬上n层楼,相邻楼层之间有一段楼梯,虽然我 ...
- c++(爬楼梯)
前两天上网的时候看到一个特别有意思的题目,在这里和朋友们分享一下: 有一个人准备开始爬楼梯,假设楼梯有n个,这个人只允许一次爬一个楼梯或者一次爬两个楼梯,请问有多少种爬法? 在揭晓答案之前,朋友们可以 ...
- Algorithm --> 爬楼梯求最大分数
爬楼梯求最大分数 如下图,最大分数是: 10+20+25+20=75. 要求: 1.每次只能走一步或者两步: 2.不能连续三步走一样的,即最多连续走两次一步,或者连续走两次两步: 3.必 ...
- climbing stairs(爬楼梯)(动态规划)
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- [Swift]LeetCode70. 爬楼梯 | Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
随机推荐
- unittest生成报告
# html报告文件路径 report_abspath = os.path.join(report_path, "result.html") fp = open(rep ...
- listalias - 列出用户和系统别名
总揽 listalias [ -s | -u ] [ 正则表达式] 描述 Listalias 按用户及系统别名每个输出一行.每行具有下列格式: <别名> <地址> (<注 ...
- linux常用的小命令
查看linux版本 uname -a 图上可知,linux内核版本为2.6.32 查看cpu核数 cat /proc/cpuinfo |grep "cores"| uniq 系统中 ...
- dll和ocx的区别
ActiveX,OLE是基于COM的一种应用,其文件后缀一般以dll和ocx结尾:ocx作为一种特殊的dll文件,具有一定的用户界面和事件响应,而dll文件只是方法和属性的集合. 一.关于DLL的介绍 ...
- fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架
题面:P2596 [ZJOI2006]书架 题解:记录每本书对应的节点编号 普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中) ...
- mysql—查询数据库表的数量
1.查看数据库表数量SELECT count(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA='dbname'; 2.获取 ...
- Django【第18篇】:Django之缓存
Django 之缓存 一.缓存 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存 ...
- 【Linux】CentOS6安装jdk1.8
1.查看官网下载地址 接受协议后,点击下载链接 查看发出的请求,获得下载地址 其中后面的AuthParam参数为本次下载的即时参数,每次都不一样 2.下载安装包 下载完后改个名 wget https: ...
- Top 8 Diagrams for Understanding Java
Reference: http://www.programcreek.com/2013/09/top-8-diagrams-for-understanding-java/ A diagram is s ...
- IntelliJ IDEA VM options(转)
Custom IntelliJ IDEA VM options # Custom IntelliJ IDEA VM options ##################JVM模式########### ...