您的位置:首页 > 职场人生

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

2017-06-29 15:59 399 查看


题目描述

大家都知道斐波那契数列,现在要求输入一个整数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、面试官要求改进算法,再使用循环实现;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: