(剑指Offer)面试题9:斐波那契数列

题目:

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

斐波那契数列的定义:

f(0)=0;f(1)=1;

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

思路:

1、递归:

根据递推公式来实现

优点:代码简单,易懂

缺点:

  • 效率低:函数递归调用过程中需要不断分配栈空间,且不断地入栈出栈,代码执行效率低;
  • 栈溢出:当递归层级太多时,会超出栈容量,导致栈溢出;
  • 复杂度高:递归调用存在大量的重复计算,时间复杂度以n的指数递增。

2、循环:

从下往上计算(动态规划),克服递归出现的缺陷

3、类似问题:

  • 青蛙跳台阶:

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

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

f(1)=1;

f(2)=2;

(2)一只青蛙一次可以跳上1级,2级。。。n级,此时一只青蛙跳上一个n级的台阶总共有多少种跳法?

f(n)=f(n-1)+f(n-2)*2

f(1)=1;

f(2)=2;

数学归纳法证明:f(n)=2^(n-1)

  • 矩阵覆盖:

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

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

f(1)=1;

f(2)=2;

代码:

#include <iostream>

using namespace std;

long long fibonacci_recursively(unsigned int n){
    if(n<=0)
        return 0;
    if(n==1)
        return 1;
    return fibonacci_recursively(n-1)+fibonacci_recursively(n-2);
}

long long fibonacci_iteratively(unsigned int n){
    if(n<2)
        return n;
    long long fibNMinusOne=1;
    long long fibNMinusTwo=0;
    long long fibN=0;
    for(unsigned int i=2;i<=n;++i){
        fibN=fibNMinusOne+fibNMinusTwo;
        fibNMinusTwo=fibNMinusOne;
        fibNMinusOne=fibN;
    }
    return fibN;
}

int main()
{
    cout <<fibonacci_iteratively(100)<< endl;
    cout <<fibonacci_recursively(100)<< endl;
    return 0;
}

在线测试OJ:

http://www.nowcoder.com/books/coding-interviews/c6c7742f5ba7442aada113136ddea0c3?rp=1

AC代码:

class Solution {
public:
	int Fibonacci(int n) {
		if(n<2)
            return n;
        int fone=0;
        int ftwo=1;
        int fsum;
        for(int i=2;i<=n;i++){
            fsum=fone+ftwo;
        	fone=ftwo;
            ftwo=fsum;
        }
        return fsum;
	}
};

 

posted @ 2015-07-08 15:49  AndyJee  阅读(906)  评论(0编辑  收藏  举报