递归函数c语言斐波纳,面试题的那些事(2)―斐波那契数列

斐波那契数列

1、写一个函数,输入n,求斐波那契数列的第n项。斐波纳挈数列的定义如下:

1e2bbba13d160facec31b5ec0d03b7f7.png

解法一:使用递归解决

long long RecurFibonacci(unsigned int n)

{

if (n <= 0)

{

return 0;

}

if (n == 1)

{

return 1;

}

return RecurFibonacci(n - 1) + RecurFibonacci(n - 2);

}

分析:思路简单理解,但是效率很低,面试官不一定会喜欢。因为在进行递归时,会重复的计算。

解法二:非递归的解法(面试官期待的解法)

long long Fibonacci(unsigned int n)

{

long long fib[2] = { 0,1 };

if (n 

{

return fib[n];

}

long long fibOne = 0;//保留Fibonacci(n-2)

long long fibTwo = 1;//保留Fibonacci(n-1)

long long fibN = 0;//第n个Fibonacci序列的结果

for (unsigned int i = 2; i <= n; i++)

{

fibN = fibOne + fibTwo;

fibOne = fibTwo;

fibTwo = fibN;

}

return fibN;

}

分析:程序的可读性虽然比较差,但是其效率很高。

测试代码:

#include

#include

using namespace std;

int main()

{

int start = GetTickCount();//从操作系统启动所经过(elapsed)的毫秒数

RecurFibonacci(40);

int end = GetTickCount();

cout <

start = GetTickCount();

Fibonacci(40);

end = GetTickCount();

cout <

getchar();

return 0;

}

2、跳台阶

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

解法分析:

最简单的情况:

如果只有1级台阶,那么显然只有一种跳法。如果有2级台阶,那么则会有2种跳法:一种是分两次跳,每次跳1阶;另外一种则是一次跳2级。

一般情况:

当n大于2时,第一次跳的时候有两种选择:一种是第一次只跳1阶,此时的跳法就是f(n-1),另外一种跳法就是第一次跳2阶,然后此时的跳法就是f(n-2)。所以总的次数就是f(n)=f(n-1)+f(n-2);很明显此时是一个斐波那契数列。

long long jumpFloor( unsigned int number)

{

unsigned int jump[2] = { 0,1 };

if (number 

{

return jump[number];

}

long long jumpOne = 1;

long long jumpTwo = 1;

long long jumpN = 0;

//n>2时为斐波那契数列

//跳一阶则方法为jumpFloor(n-1)

//跳两阶则方法为jumpFloor(n-2)

for (unsigned int i = 2; i <= number; i++)

{

jumpN = jumpOne + jumpTwo;

jumpOne = jumpTwo;

jumpTwo = jumpN;

}

return jumpN;

}

3、变态跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

解法分析:

使用数学归纳法:

1)当n为1的时候,只有1种跳法

2)当n为2的时候,可以有(1,1)和(2)共2种跳法

3)当n为3的时候,可以有(1,1,1)、(1,2)、(2,1)、(3)共4种跳法

4)当n为4的时候,可以有(1,1,1,1)、(1、2、1)、(1、3)、(1、1、2)、(2,1,1)、(2,2)、(3,1)、(4)共8种跳法

.......

由数学归纳法得f(n)=2的(n-1)次方。

long long jumpFloorII(unsigned int number) {

if (number <= 0)

{

return 0;

}

return pow(2, number - 1);

}

4、矩形覆盖

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

解法分析:

假设当n为1的时候,只有1种覆盖方法

当n>2时,覆盖大矩形的最左边时有2种覆盖方法:当竖着放的时候右边还剩下2*(n-1)个区域,此时的覆盖方法为f(n-1);当横着放的时候,那么最左下角也必须横着放,那么右边还剩下2*(n-2)个矩形,此时的方法为f(n-2);总的方法为f(n)=f(n-1)+f(n-2),又是斐波纳挈数列。

long long rectCover(unsigned int number) {

if (number 

{

return 0;

}

long long stepOne = 0;

long long stepTwo = 1;

long long step = 0;

for (unsigned int i = 1; i <= number; i++)

{

step = stepOne + stepTwo;

stepOne = stepTwo;

stepTwo = step;

}

return step;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值