首页 > 剑指offer:面试题10- I. 斐波那契数列

剑指offer:面试题10- I. 斐波那契数列

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:

F(0) = 0,   F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.

斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2
输出:1

示例 2:

输入:n = 5
输出:5

提示:

0 <= n <= 100

解题:

方法一:递归

(1)递归:函数自己调用自己

(2)递归的"缺陷":递归到一定程度,会发生"栈溢出"

(3)递归的"时间复杂度":递归总次数*每次递归的次数

(4)递归的"空间复杂度":递归的深度*每次递归空间的大小(注意:"每次递归空间的大小"是个常数,可以基本忽略不计)

    递归的"深度":树的高度(递归的过程是一个"二叉树")

  • 时间复杂度

假设n对应复杂度T(n),由于if( n <= 1 )执行1次,f(n-1)执行1次,f(n-2)执行1次,然后f(n-1)和f(n-2)执行一次,因此有T(n)=T(n-1)+T(n-2)+4,忽略次要项,得到T(n)=T(n-1)+T(n-2),根据数学知识可得通项式为

下面继续分析下,不通过数学计算,估算其上下极限

上限:令T(n-2)约等于T(n-1),则T(n)=T(n-1)+T(n-2)=2T(n-1)=2*2*T(n-2)=....=2^n*T(0)=2^n,即为O(2^n)

下限:令T(n-1)约等于T(n-2),则T(n)=T(n-1)+T(n-2)=2T(n-2)=2*2*T(n-4)=....=2^(n/2)*T(0)=2^(n/2),即为O(2^(n/2))

所以最后可得到结果,其时间复杂度结果位于O(2^(n/2))和O(2^n)之间

  • 空间复杂度

跟所有递归调用一样,每次调用一次,都会进行压栈操作,因此下面分析函数调用时栈空间情况,要求f(n)会执行f(n-1)+f(n-2)需要压栈一次,然后求f(n-1)会执行f(n-2)+f(n-3)需要压栈一次,....,最后直到到f(1),这里以f(5)为例,那么栈情况如下图所示

递归算法的空间复杂度:递归的深度*每次递归所需的辅助空间的个数

而树的高度即为递归的深度。

则易知空间复杂度为O(n)

class Solution {
public:int fib(int n) {if(n==0) return 0;if(n==1) return 1;return (fib(n-1)+fib(n-2))%1000000007;}
};

方法二:动态规化法

动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划(DP)。

时间复杂度O(n),空间复杂度O(1)

class Solution {public:int fib(int n) {if(n==0) return 0;int func1=0;int func2=1;for(int i=2;i<=n;i++) {int temp=f2;func2=(func1+func2)%1000000007;func1=temp;}   return func2;}
};

 

更多相关:

  •   最近一直在学习Deep Frist Search,也在leetcode上练习了不少题目。从最开始的懵懂,到现在遇到问题基本有了思路。依然清晰的记得今年2月份刚开始刷题的时做subsets的那个吃力劲,脑子就是转不过来到底该如何的递归,甚至试过使用debugger一步步的来看看堆栈到底是如何调用和返回的。经过了几个月的训练后,答题有...

  • 链接: https://www.nowcoder.com/acm/contest/139/B   题意: 求满足以下条件的n*n矩阵A的数量模m:A(i,j) ∈ {0,1,2}, 1≤i,j≤n.A(i,j) = A(j,i), 1≤i,j≤n.A(i,1) + A(i,2) + ... + A(i,n) = 2, 1≤i≤n.A(...

  • LeetCode 191 Number of 1 Bits  解法一(较为传统都解法):使用将n不断右移,并与1想&得到1的个数;(也有使用除法/2的,明显除法的运行效率要低于位移) 时间复杂度:0(logn) 1 int hammingWeight(uint32_t n){ 2 int count=0; 3...