Python求解登楼梯问题(京东2016笔试题)

问题:假设一段楼梯共15个台阶,小明一步最多能上3个台阶,那么小明上这段楼梯一共有多少种方法?

解析:从第15个台阶上往回看,有3种方法可以上来(从第14个台阶上一步迈1个台阶上来,从第13个台阶上一步迈2个台阶上来,从第12个台阶上一步迈3个台阶上来),
同理,第14个、13个、12个台阶都可以这样推算,从而得到公式f(n) = f(n-1) + f(n-2) + f(n-3),其中n=15、14、13、...、5、4。然后就是确定这个递归公式的结束条件了,
第一个台阶只有1种上法,第二个台阶有2种上法(一步迈2个台阶上去、一步迈1个台阶分两步上去),第三个台阶有4种上法。

Python实现

1.递推法

1 def climbStairs1(n):
2     a = 1
3     b = 2
4     c = 4
5     for i in range(n-3):
6         c, b, a = a+b+c, c, b
7     return c

2.递归法

def climbStairs2(n):
    first3 = {1:1, 2:2, 3:4}
    if n in first3.keys():
        return first3[n]
    else:
        return climbStairs2(n-1) +                climbStairs2(n-2) +                climbStairs2(n-3)

看起来,问题似乎解决了。但是再多考虑一点,方法2中使用递归效率非常低,不仅因为递归时上下文的保存和恢复比较耗时,还因为涉及大量的重复计算。

因此进一步改进,可使用functools标准库提供的缓冲修饰器lru_cache来缓解这个问题。

@functools.lru_cache(maxsize=64)
def climbStairs3(n):
    #带缓冲的递归法
    first3 = {1:1, 2:2, 3:4}
    if n in first3.keys():
        return first3[n]
    else:
        return climbStairs3(n-1) +                climbStairs3(n-2) +                climbStairs3(n-3)

下面是测试代码 ,运行一次就可以看出不缓冲的递归方法效率之低。

n = 25
for f in (climbStairs1, climbStairs2, climbStairs3):
    start = time.time()
    for i in range(1000):
        result = f(n)
    delta = time.time() - start
    print(f.__name__, result, delta)

Java实现

1.递推法

public static int climbStairs1(int n){
        int a = 1;
        int b = 2;
        int c = 4;
        for(int i=0;i<n-3;i++){
            c = a + b + c;
            b = c - a - b;
            a = c - b - a;
        }
        return c;
    }

2.递归法

public static int climbStairs2(int n){
        int first[] = new int[3];
        first[0] = 1;
        first[1] = 2;
        first[2] = 4;
        if(n<=3){
            return first[n-1];
        }
        else{
            return climbStairs2(n-1) + climbStairs2(n-2) + climbStairs2(n-3);
        }
    }

参考资料:微信号:Python_xiaowu

时间: 2024-08-29 18:24:02

Python求解登楼梯问题(京东2016笔试题)的相关文章

Python求解啤酒问题(携程2016笔试题)

问题描述:一位酒商共有5桶葡萄酒和1桶啤酒,6个桶的容量分别为30升.32升.36升.38升.40升和62升,并且只卖整桶酒,不零卖.第一位顾客买走了2整桶葡萄酒,第二位顾客买走的葡萄酒是第一位顾客的2倍.那么,本来有多少升啤酒呢?解析:由于该酒商只卖整桶酒,简单分析几个桶的容量可知,第二位顾客必须买走剩下的3桶葡萄酒才有可能是第一位顾客的2倍.假设第一位顾客买走的葡萄酒共L升,那么第二位顾客买走的是2L升.也就是说,葡萄酒的总数应该能被3整除.所以,解法就呼之欲出了. Python 解法1 1

DP - 2016网易杭研笔试题A

2016网易杭研笔试题A Problem's Link ---------------------------------------------------------------------------- Mean: 有一个边长为n的立方体,内部的每一个小立方体内有一个数字.如果取了当前这个小立方体,则小立方体的: 1.上下相邻两层将会消失; 2.前后相邻两列将会消失; 3.左右相邻两个将会消失; 找出一种取法,使得取到的数的sum最大,输出sum. analyse: 现场面试时挂在这题上了

&lt;转&gt;网易2016实习生前端笔试题部分总结

网易2016实习生前端笔试题部分总结 原文地址:http://www.cnblogs.com/venoral/p/5325202.html 这只是部分题,答案为个人观点如有错误欢迎指出,感觉考点都挺基础,但是很注重考细节方面,通过整理也知道自己在CSS3和HTML5,网络知识等方面的不足还是得多学多练多思考.攒rp,希望自己在明天360笔试中能轻松答过~ css 1.多选 //HTML <p>很长的一段文字,很长的一段文字,很长的一段文字,特别长的文字</p> //CSS p{ w

Python 的笔试题

其实大多数说学习Python 是纯兴趣,真的我不信,许多人已经工作了,没有那么多时间搞自己的纯兴趣了,都会为了生活奋斗,可以说转行来学python 就是未来加薪,当然,小编现在也快要准备工作了,所以也开始准备笔试,面试. 所以为了充实自己,小编决定写自己见到的笔试题和面试题.可能要写好长时间,一时半会写不了多少,只能说遇到多少写多少吧,但是只要小编有时间,会持续上传. 2017.9.6 问题一:以下代码将输出什么? list = ['a', 'b', 'c', 'd', 'e'] print l

前端试题-2016年阿里前端开发工程师笔试题6,7,8题的解法

2016年阿里前端开发工程师笔试题(只有题,没有答案): http://www.cnblogs.com/sdgf/archive/2015/08/18/4740698.html 第6题:请在____处填写答案,从而达到题目的要求 var arr = [1, 2, 3, 4, 5]; var result = arr.sort(_______________________________).join("+"); console.log(result); 解答:在排序当中,如果需要按照某

Python求解非线性方程

原文地址:http://blog.csdn.net/ville_zeng/article/details/25370053,转载请注明出处! 昨晚一朋友问了我道数学题:已知弧长l=156,弦长d=140,求半径R和夹角a. 我试了下,方程比较好列,但是求解的话就比较费劲了,心想要是用Matlab的话也就瞬间的事儿,可电脑没安装Matlab,然后想到Python的一个数学库scipy,研究下,是可以解决的. 方程如下: ·      cos(a) = 1 - d^2 / (2*R^2) ·    

2018春招-今日头条笔试题-第三题(python)

题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) 解题思路: 本题的做法最重要的应该是如何拼出'1234567890',对于输入表达试获得对应的结果利用python内置函数eval()即可以实现.利用5个字符串来表达'1234567890',如下(为了好看,里面加了tab空格符) '66666 ....6 66666 66666 6...6 66666 66666 66666 66666 66666''6...6 ....6 ....6 ....6 6...6 6.... 6

python 饥饿的小易(网易笔试题)

本周早些时候,学弟给我发了一道网易的笔试题,饥饿的小易,感觉有点意思-分享给大家 题目描述: 小易总是感觉饥饿,所以作为章鱼的小易经常出去寻找贝壳吃.最开始小易在一个初始位置x_0.对于小易所处的当前位置x,他只能通过神秘的力量移动到 4 * x + 3或者c.因为使用神秘力量要耗费太多体力,所以它只能使用神秘力量最多100,000次.贝壳总生长在能被1,000,000,007整除的位置(比如:位置0,位置1,000,000,007,位置2,000,000,014等).小易需要你帮忙计算最少需要

python最新笔试题

这是笔者面试小十家公司后呕心沥血总结的一些笔试编程题~具体公司就不透露了.哎,说多了都是泪啊. 1.二分法查找: l = [1, 2, 3, 4, 5, 6, 7, 8, 9] find_num = int(input('请输入一个数字:')) start = 0 end = len(l) - 1 while True: middle = (start + end) // 2 if find_num == l[middle]: print('找到了!索引是:', middle) break el