【剑指offer】面试题 10:斐波那契数列及其推广

来源:互联网 发布:凌渡车钥匙淘宝图片 编辑:程序博客网 时间:2024/06/18 07:51

题目描述

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

n<=39


时间限制:1秒 空间限制:32768K 热度指数:153571


思路


1、用递归来实现,但是递归存在调用栈溢出的风险。


调用栈溢出是因为递归的计算中,每次函数调用在内存栈中分配空间,而每个进程的栈的容量都是有限的。


当递归调用的层级太多时,就会超出栈的容量,从而导致调用栈的溢出。


2、从下往上计算。根据 f(0) 和 f(1) 算出 f(2),再根据 f(1) 和 f(2) 算出 f(3)...以此类推,就可以算出 f(n)。


时间复杂度是 O(n).


参考代码


Python实现


# -*- coding:utf-8 -*-class Solution:    def Fibonacci(self, n):        # write code here        tempArray = [0, 1]        if n <= 0:            return 0        elif n == 1:            return 1        elif n == 2:            return 1        else:            for i in range(2, n + 1):                tempArray[i % 2] = tempArray[0] + tempArray[1]            return tempArray[i % 2]


题目推广


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



思路


其实这是一个斐波那契数列的应用。青蛙要跳上 1 级台阶时,有 1 种跳法;青蛙要跳上 2 级台阶时,有 2 种跳法;


(第一种:先跳 1 级,再跳 1 级;第二种:直接跳 2 级)


这可以抽象为:要跳 n 级,先跳 1 级,再考虑跳 n - 1 级;先跳 2 级,再考虑跳 n - 2 级。


所以跳 n 级的跳法:f(n) = f(n - 1) + f(n - 2),这就是斐波那契数列的公式。


参考代码


# -*- coding:utf-8 -*-class Solution:    # 青蛙跳台阶, 每次可以跳1级或2级    def jumpFloor(self, number):        # write code here        tempArray = [1, 2]        if number >= 3:            for i in range(3, number + 1):                tempArray[(i + 1) % 2] = tempArray[0] + tempArray[1]        return tempArray[(number + 1) % 2]


题目推广


将上题中的条件改为“一次可以跳上 1 级台阶,一次也可以跳上 2 级台阶,...,一次也可以跳上 n 级台阶”,求青蛙跳


上 n 级台阶的跳法?


思路


青蛙跳 1 级台阶的跳法是 f(1) = 1


青蛙跳 2 级台阶的跳法是 f(2) = 1 + f(1) = 2


青蛙跳 3 级台阶的跳法是 f(3) = 1 + f(1) + f(2) = 4


....


青蛙跳 n 级台阶的跳法是 f(n) = 1 + f(1) + f(2) + ... + f(n - 1) = 2^(n - 1)


其中:1 表示一次性跳上 n 级台阶的方法



参考代码


# -*- coding:utf-8 -*-class Solution:    # 可以跳 1 级,也可以跳 2 级,... ,也可以跳 n 级    def jumpFloorII(self, number):        ans = 1        if number >= 2:            for i in range(number-1):                ans = ans * 2        return ans



总结


1、遇到需要多次重复计算的问题,通常是用递归或循环两种方法来实现的;


2、递归:在一个函数的内部调用这个函数本身;


3、循环:通过设置计算的初始值及终止条件,在一个范围内重复运算;


4、想要算法 / 代码简单,用递归;


5、递归会产生调用栈溢出,原因是递归调用的层级太多,会超过调用栈的容量;


6、面试优先写出递归算法,实现简单;


7、面试官要求改进算法,再使用循环实现;


















原创粉丝点击