爬楼梯问题,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 ...
随机推荐
- JavaEE高级-Maven学习笔记
Maven简介 1.Maven是一款服务于Java平台的自动化构建工具. 2.构建: - 概念:以“Java源文件”.“框架配置文件”.“JSP”.“HTML”.“图片”等资源为“原料”,去“生产”一 ...
- PAT Basic 1048 数字加密 (20 分)
本题要求实现一种数字加密方法.首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对应位的数字相加后对 13 取余——这里用 J 代表 ...
- macOS安装wget
brew install wget 或者 curl -O http://ftp.gnu.org/gnu/wget/wget-1.13.4.tar.gz tar xzvf wget-1.13.4.tar ...
- varnish流程图
varnish流程图
- Spring配置文件出错
问题描述: Element 'xxxxxxx' cannot have character [children],because the type's content type is element- ...
- mysql BETWEEN操作符 语法
mysql BETWEEN操作符 语法 作用:选取介于两个值之间的数据范围.这些值可以是数值.文本或者日期.大理石平台 语法:SELECT column_name(s) FROM table_name ...
- codevs 2039 骑马修栅栏 USACO x
题目描述 Description Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏 ...
- influxDB 1.3 中文文档
influxDB是一个旨在处理高并发写入和查询负载的时序数据库,它是TICK框架的第二部分,influxdb用于任何包含大量时序数据应用的后台存储,包括Devops监控.应用指标数据.物联网传感器数据 ...
- tp5关联模型进行条件查询
public function wordOne(){ return $this->hasOne('TeachWord','id','w_id')->field('id,pid,title' ...
- mysqldump常用使用
1:导出数据库sakila的表结构mysqldump -uroot -ppwd -d sakila > /data/tmp/sakila.sql; 2:导出数据库sakila下表employee ...