zoukankan      html  css  js  c++  java
  • 【剑指offer学习记录】10-斐波那契数列

    10-斐波那契数列

    题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39

    n=0时,f(n)=0 n=1时,f(n)=1 n>1时,f(n)=f(n-1)+f(n-2)

    题目解析

    斐波那契数列是一道经典的递归解法的题目。

    此题有两种思路,一种是正常的递归方法,但是会产生很多的冗余项,会有很多重复计算项;

    因此第二种思路就是按照斐波那契数列的递归计算的状态树,从下往上根据小项来推大项,这样每一项只用计算一次,这种方法代码实现上体现为循环。

    代码实现

     1  #方法一:递归法
     2  class Solution:
     3      def Fibonacci(self,n):
     4          if n<=0:
     5              return 0
     6          else n==1:
     7              return 1
     8          return self.Fibonacci(n-1) + self.Fibonacci(n-2)
     9      
    10  # 方法二:自下而上的循环方法
    11  class Solution:
    12      def Fibonacci(self, n):
    13          res = [0,1]
    14          if n<2:
    15              return res[n]
    16          MinusOne = 1
    17          MinusTwo = 0
    18          Nsum = 0
    19          for i in range(2, n+1):
    20              Nsum = MinusOne + MinusTwo
    21              MinusTwo = MinusOne
    22              MinusOne = Nsum
    23          return Nsum   

    拓展题目一:跳台阶

    一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

    题目解析

    遇到这种有多个状态,而求得结果是多个固定状态组合的结果,都可以考虑递归方法。

    在此题中,可以把n级台阶的跳法看做函数f(n)。

    假设有n个台阶,则跳第一阶的时候,有两个状态:

    第一个状态是跳一阶,剩余n-1,则此时的跳法有f(n-1)种,依赖于后n-1个台阶的跳法

    第二个状态是跳二阶,剩余n-2,则此时的跳法有f(n-2)种,依赖于后n-2个台阶的跳法

    所以f(n) = f(n-1) + f(n-2)

    代码实现

     
     1 class Solution:
     2      def JumpFloor(self, number):
     3          if number == 1:
     4              return 1
     5          if number == 2:
     6              return 2
     7          small, big = 1,2
     8          #这里要注意,因为是跳台阶,到第n的时候是不会动的,所以不包含n,和斐波那契数列求和是不同的
     9          for i in range(2, number):
    10              sum_i = small + big
    11              small = big
    12              big = sum_i
    13          return sum_i

    拓展题目二:跳台阶进阶

    一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

    解题方法

    对于此类状态很多的情况,也是先将所有的状态列出来。

    首先是f(n)情况,f(n) = f(n-1) + f(n-2) + ... +f(1) + f(0)

    再看f(n-1)情况,f(n-1) = f(n-2) + f(n-3) + f(n-4) + ... + f(1) + f(0)

    将f(n) - f(n-1),有f(n) - f(n-1) = f(n-1),所以有f(n) = f(n-1),其中n>0,f(1) = 1

    所以可以归纳到f(n) = 2^ (n-1)

    代码实现

    对应的实现有两种,一种是f(n) = f(n-1),一种是直接使用得到的公式f(n) = 2^ (n-1)

     
     1 class Solution:
     2      def Jump1(self, number):
     3          if number<=0:
     4              return 0
     5          return 2**(number-1)
     6      def Jump2(self, number):
     7          if number<=0:
     8              return 0
     9          if number == 1:
    10              return 1
    11          return 2*self.Jump(number - 1)

    10-扩展题目三:矩形覆盖

    我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2n的大矩形,总共有多少种方法?

    题目解析

    此题依旧是斐波那契数列解题的思路,首先根据某一状态进行具体分析,然后找到状态的递推规律。

    首先假设是2*8的矩阵,那么可以将单元矩形竖着一列放一个,则剩余部分为2*7的矩阵。

    如果是将单元矩阵横着放,则要横着放两个,然后剩余部分为2*6矩阵。

    根据这种转换状态,可以知道,f(8) = f(7) +f(6)

    代码实现

     1  class Solution: 
     2      def rectCover(self, number):
     3          if number<=0:
     4              return 0
     5          if number == 1:
     6              return 1
     7          if number == 2:
     8              return 2
     9          small, big = 1, 2
    10          #注意这里到f(n)的话也是要求解的,因为对于n的情况也要覆盖,所以要包含n,因此边界是n+1不包含
    11          for i in range(3, number + 1):
    12              sum_i = small + big
    13              small = big
    14              big = sum_i
    15          return big

                 
  • 相关阅读:
    【转】return 使用示例
    java基础_二维数组的行和列
    新版SQL授权用户时报错 near 'IDENTIFIED BY '密码' with grant option' at line 1
    GO kafka sarama 生产者 消费者 简单 实现
    Windows 安装kafka
    windows 连接nsq
    reflect: call of reflect.Value.NumField on ptr Value
    django 数据库 mysql 事务 处理
    python 类的继承
    python 中 insert 返回 None
  • 原文地址:https://www.cnblogs.com/szxyx/p/13307825.html
Copyright © 2011-2022 走看看