面试题10:斐波那契数列
题目一:
求斐波那契数列的第n
项,其定义如下:
F
(
0
)
=
0
,
F
(
1
)
=
1
F(0) = 0,F(1) = 1
F(0)=0,F(1)=1
F ( n ) = F ( n − 1 ) + F ( n − 2 ) ,其中 n > 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1 F(n)=F(n−1)+F(n−2),其中n>1
思路:
可以使用递归的方式实现这个,也可以使用循环的方式实现它。
但是使用递归的方式的话就会产生很多重复节点的运算就可以看成两边子树有很多重复的部分多计算了,这也就意味着计算量会随着n的增大而急剧增大,并且可能还有栈溢出的情况产生。
使用循环的方式可以从下往上计算,首先根据f(0)
和f(1)
计算出f(2)
,在根据f(1)
和f(2)
计算出f(3)
…,依次类推就可以得到第n
项。
代码:
/*使用递归实现*/
long long Fibonacci(unsigned int n){
if(n<=0)
return 0;
if(n==1)
return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}
/*使用循环实现,时间复杂度为O(n)*/
long long Fibonacci(unsigned int n){
int result[2]={0,1};
if(n<2)
return result[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;
}
题目二:
假设你正在爬楼梯。需要 n
阶你才能到达楼顶。每次你可以爬 1
或 2
个台阶。你有多少种不同的方法可以爬到楼顶呢?
思路:
先是简单情况,当只有一阶楼梯那么,只有一种方法,当有两阶楼梯那么就有2种方法。所以由此衍生,如果有n(n>2)
阶楼梯,第一次跳的时候就有两种选择:一是第一次就只跳1级,此时跳法数目等于后面剩下的n-1
级台阶的跳法数目,即为f(n-1)
;二是第一次跳两级,此时跳法数目等于后面剩下的n-2
级台阶的跳法数目,即为f(n-2)
。因此,n级楼梯的不同跳法就是这两个的和为f(n)=f(n-1)+f(n-2)
,这也是一个斐波那契数列。
这个也可以用动态规划的思路:也就是现在的状态可以由前面的状态推导出来。
代码:
/*这里是动态规划的方法,斐波那契数列的方法在上面*/
int climbStairs(int n) {
if(n==1)
return 1;
vector<int> V(n+1);
V[1] = 1;
V[2] = 2;
for(int i=3;i<=n;i++){
V[i] = V[i - 1] + V[i - 2];
}
return V[n];
}