题目描述:一只青蛙一次可跳上一个台阶或者两个台阶,求该青蛙跳上n级台阶有多少种跳法。
拿到该题,首先会想到台阶该有多少阶?1阶,2阶,……10阶,……100阶,……
台阶数 | 跳法 |
---|---|
1 | 1 |
2 | 2 |
3 | 3 |
4 | 5 |
…… | …… |
n | …… |
现在就很清楚了,其实青蛙跳台阶问题就是fibonacci数列问题的求解。我们应该多考虑的是代码优化问题。
一:递归求解
不假思索想到的是递归写法,直接上代码。
int fibonacci(int n)
{
if(n <= 2)
return 1;
else
return (fibonacci(n-1) + fibonacci(n-2));
}
或者直接写成:
int fibonacci(int n)
{
return (n<=2)?1:((fibonacci(n-1) + fibonacci(n-2));
}
这样写,暂且不说时间复杂度问题,首先返回类型int,如果数字比较大,int类型就存不下,该处应该用long long类型。第二种写法也不见难以阅读。
- 除了效率问题,递归还有更加严重的后果,就是调用栈溢出,每一次调用函数都会在内存栈中分配空间,但是每个进程的栈容量有限,调用层级过多就会超出栈容量,造成栈溢出。
递归调用在这里的时间复杂度是n的指数方式递增的,效率不高,代码有待改进。
二:非递归求解
//迭代实现
#include<stdio.h>
#include<stdlib.h>
long long fibonacci(int n)
{
int arr[2] = { 0, 1 };
if (n < 2)
return arr[n];
long long fibOne = 1;
long long fibTwo = 0;
long long fibN = 0;
for (int i = 2; i <= n; i++)
{
fibN = fibOne + fibTwo;
fibTwo = fibOne;
fibOne = fibN;
}
return fibN;
}
void Test()
{
int n = 40;
long long reasult = 0;
reasult = fibonacci(n);
printf("the reasult is : %Ld\n", reasult);
}
int main()
{
Test();
return 0;
}
以上实现方法代码时间复杂度是O(n);