《剑指Offer-Java实现-斐波那契数列-青蛙跳楼梯

题目一:求斐波那契数列的第n项。

写一个函数,输入你,求斐波那契数列的第n项。

最原始的递归方法:

public static int addFibo(int n) {
		int[] result = {0,1};
		if(n<2)return result[n];
		return addFibo(n-1)+addFibo(n-2);
	}

优点:递归函数的代码十分的简洁,审阅起来十分具有美感。

缺陷:1)使用递归的效率很低,因为很多数字都被重复计算。例如计算10要计算9和8,计算9要计算8和7,此时8便被计算了两次,随着n的增多,被重复计算的数字将会越来越多。

2)递归函数的实质是函数调用函数本身,而每一次函数的调用都要在内存中分配空间以保存进行参数,返回地址等。而且往栈里弹出数据,插入数据是需要时间的。最重要的是,多层的递归可能造成调用栈溢出。

面试官亲睐的方法:

private static int Fibonacci(int n) {
		int[] result = { 0, 1 };
		if (n < 2)
			return result[n];
		int fiboOne = 1;
		int fiboTwo = 0;
		int fn = 0;
		for (int i = 2; i < n; i++) {
			fn = fiboOne + fiboTwo;
			fiboTwo = fiboOne;
			fiboOne = fn;
		}
		return fn;
	}

我们可以使用中间变量将中间值暂且保存起来,实现良好的使用。

题目二:青蛙跳台阶问题。

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

直接先上代码:

private static int Fibonacci(int n) {
		if(n<=0)return 0;
		if(n==1) {
			return 1;
		}else if(n==2) {
			return 2;
		}
		int fiboOne = 2;
		int fiboTwo = 1;
		int fn = 0;
		for (int i = 3; i <= n; i++) {
			fn = fiboOne + fiboTwo;
			fiboTwo = fiboOne;
			fiboOne = fn;
		}
		return fn;
	}

分析:我们将跳n阶台阶看成函数f(n),那么f(n)= f(n-1)+f(n-2);因为青蛙只能跳1阶或者2阶;这样我们就能看出这是一个斐波那契数列了,只是初始值1,2可能与前面不同。分析得到,当n=1 时,fn=1;当n=2时,fn=2; 


超级青蛙跳台阶:

如果在青蛙跳台阶中,将条件改成:一只青蛙一次可以跳上1个,2个,。。。。n个台阶,此时该青蛙跳上一个n级当台阶总共有多少中跳法?

奉上代码;

private static int superFibonacci(int n) {
		if(n==1) return 1;
		if(n==2) return 2;
		return 2*superFibonacci(n-1); 
	}


分析:同样的,将青蛙跳台阶看成函数f(n)。第一步有n种跳法;

1)跳1步,还剩下f(n-1)种跳法;

2)跳2步,还剩下f(n-2)种跳法;

3)跳3步,还剩下f(n-3)种跳法;

.......

f(n)= f(n-1)+f(n-2)+f(n-3)+......f(1)+1;1⃣️   这里的1指的是直接跳n层台阶;

f(n-1)=f(n-2)+(n-3)+f(n-4)+.....f(1)+1;2⃣️

1⃣️减去2⃣️得到:fn = 2f(n-1)

题目一:求斐波那契数列的第n项。

猜你喜欢

转载自blog.csdn.net/u010947534/article/details/88050983
今日推荐