【剑指Offer】第9题-斐波那契数列-Python

在这里插入图片描述

解法一 递归

通常用递归的解法会比较简洁,但也有显著的缺点。递归由于是函数自己调用自己,而函数调用是有时间和空间的消耗的。每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址及临时变量。而且往栈里压入数据和弹出数据也需要时间。

另外,递归中有可能很多计算都是重复的,从而对性能造成很大影响。递归的本质是把一个问题分割成多个小问题,如果多个小问题存在相互重叠的部分,那么就存在重复的计算。

递归还有可能引起更重要的问题,调用栈溢出。每一次函数调用在内存栈中分配空间,而每个进程的栈的容量是有限的,当递归调用的层级太多,就会超出栈的容量,从而导致栈溢出。

def climbStairs(self, n):
    """
    :type n: int
    :rtype: int
    """
    if n<3:
        return n
    return self.climbStairs(n-1)+self.climbStairs(n-2)

这里的递归解法存在严重的效率问题,会重复的计算很多项。而重复计算的节点个数随着n的增加急速增大
在这里插入图片描述

解法二 保存数列中间项

上面递归的缺点在于计算了很多重复项。可以通过保存数列中间项的方法来减少重复计算。下次需要计算的时候先查找是否计算过,如果计算过直接调用即可。

def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n<3:
            return n
        temp = {}
        if n in temp:
            return temp[n]
        else:
            value = self.climbStairs(n-1)+self.climbStairs(n-2)
            temp[n]=value
            return value
        

解法三 逆向计算

更简单的方法是从下往上计算。首先根据f(0)和f(1)计算出f(2)。再根据f(1)和f(2)计算出f(3)。并且不保存计算中间结果。这种思路的时间复杂度是O(n)

def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n<3:
            return n
        temp = 0
        a = 1
        b = 2
        for i in range(3,n+1):
            temp = a + b   # 计算新值
            a = b          # 更新a b
            b = temp
        return temp

相似题目 爬楼梯

70. 爬楼梯
在这里插入图片描述
这个题目可以看做是斐波那契数列的应用。
首先考虑最简单的情况,如果只有1级台阶,显然只有一种跳法。如果有2级台阶,那就有两种跳的方法:一种是分两次跳,每次跳一级。一种是一次就跳两级。

接下来讨论一般的情况。 当n>2时,第一次跳的时候就有两种不同的选择。一是第一次只跳一级,此时数目为后面n-1阶跳法数目f(n-1).另一种是第一次跳2级,此时数目为后面n-2阶跳法数目f(n-2).
因此n级台阶的不同跳法的数目为f(n)=f(n-1)+f(n-2)。这时就可以看做是斐波那契数列了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值