面试题: 求解斐波那契数列
/*
题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。
斐波那契数列的定义如下:
0 n = 0;
f(n) = 1 n = 1;
f(n-1) + f(n-2) n > 1;
*/
题目分析:
/*
要做这道题首先得了解什么是斐波那契数列,例如:
1 1 2 3 5 8. . . . . . 这样一个递增序列,且从第二个数起,每个数是前两个数的和。
很多同学立马就想到了递归,因为在讲递归的书中,把这个斐波那契数列可谓是百试不
爽! 那么递归到底是不是我们面试时应该答出的最佳答案呢?
算法选择: 既然如此,我们就先以递归求解;
代码如下:
#include<stdio.h>
#include<stdlib.h>
long long Fibonacci(unsigned int n)
{
if(n<=0)
return 0;
if(n==1)
return 1;
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
int main()
{
int n = 100;
printf("%u\n",Fibonacci(n));
system("pause");
return 0;
}
/*
递归的优点是会让代码看起来比较简洁,但同时也有显著的缺点。
递归调用由于是函数调用自身,二函数的调用是有时间和空间的消耗的;具有严重的效
率问题;当然,如果面试官没有特别的要求,应尽量采用递归;
就斐波那契数列而言,递归并不是最令面试官满意的答案!下面展示时间复杂度为
O(N)的常规算法!
*/
代码如下:
#include<stdio.h>
#include<stdlib.h>
long long Fibonacci(unsigned int n)
{
long long one = 1;
long long two = 0;
unsigned int i = 0;
int tmp = 0;
if(n <= 0)
return 0;
if(n==1)
return 1;
for(i = 2; i <= n; ++i)
{
tmp = one + two;//前两个数的和产生新的斐波那契数;
two = one; //第n个数又变成第n-1个数;
one =tmp; //新的斐波那契数又成为新的第n个数;
}
return tmp;
}
int main()
{
int n = 100;
printf("%u\n",Fibonacci(n));
system("pause");
return 0;
}
/*
扩展题目:一只青蛙一次可以跳上一级台阶,也可以跳上两级。求:
该青蛙跳上一个n级的台阶总共有多少种跳法?
*/
/*
可以把n级台阶时的跳法看成是n的函数,记为f(n);
当n>2时,第一次跳的时候就有两种不同的选择:
一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目;
即为f(n-1);另一种选择是第一次跳2级,
此时跳法数目等于后面剩下n-2级台阶的跳法数目,即为f(n-2)。
因此,n级台阶的不同跳法的总数f(n)=f(n-1)+f(n-2)。分析到这里,
不难看出这实际上就是斐波那契数列了。
1 2 3 5 . ....
*/
#include<stdio.h>
#include<stdlib.h>
int Jump(int n)
{
if(n<=0)
return 0;
if(n==1)
return 1;
if(n==2)
return 2;
return (Jump(n-1)+Jump(n-2));
}
int main()
{
int n = 4;
printf("%d\n", Jump(n));
system("pause");
return 0;
}