爬楼梯问题,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 ...
随机推荐
- 时间戳转换日期格式 - Vue
日常开发中经常会遇到时间相关的问题,服务端返回的数据都是以时间戳的方式,那么需要将其处理转化为对应的时间格式,具体方式如下: 一.filters 中 formatDate 方法实现 <scrip ...
- 关于cron4j的使用
cron4j的主要实体是调度程序.使用it.sauronsoftware.cron4j.scheduler实例,您可以在一年中的固定时间执行任务.调度程序可以每分钟执行一次任务,每五分钟执行一次,星期 ...
- fpga为什么要用nios 开发
同一个项目可以用NIOS2也可以不用就可以完成,这句话说对也可以说不对,这要看是一个什么样的项目,你那样问的话可就说明有CPU和没CPU下的使用情况你还没有搞清楚,这两者并没有完全分开,简单的说就是有 ...
- Codeforces1234F. Yet Another Substring Reverse(状压dp)
题目链接:传送门 思路: 由于只能翻转一次子串,就相当于找出两个不连续的子串,把在后面的一个子串翻转过来,和第一个子串拼接. 因为题目仅要求子串中的字符不重复,所以字符的先后顺序无关,翻转的操作就相当 ...
- 使用glew和glad 新建窗口
一.添加头文件 首先,将头文件加到项目的.cpp文件中 #include <glad/glad.h> 2 #include <GLFW/glfw3.h> 注: 包含glad的头 ...
- java Thread源码分析(二)
一.sleep的使用 public class ThreadTest { public static void main(String[] args) throws InterruptedExcept ...
- 【牛客Wannafly挑战赛23】F 计数
题目链接 题意 给定一张边带权的无向图,求生成树的权值和是 k 的倍数的生成树个数模 p 的值. \(n\leq 100,k\leq 100,p\mod k=1\) Sol 看见整除然后 \(p\mo ...
- 【leetcode】1171. Remove Zero Sum Consecutive Nodes from Linked List
题目如下: Given the head of a linked list, we repeatedly delete consecutive sequences of nodes that sum ...
- 【leetcode】1146. Snapshot Array
题目如下: Implement a SnapshotArray that supports the following interface: SnapshotArray(int length) ini ...
- 【转载】MIMO技术杂谈(一):鱼与熊掌能否兼得?--浅谈分集与复用的权衡
原文链接(向作者致敬):http://www.txrjy.com/thread-667901-1-1.html 无线通信世界在过去的几十年中的发展简直是爆发式的,MIMO(多发多收)技术的出现更是 ...