- 题目描述:
写一个函数,输入n,求斐波那契数列的第n项。
-
分析:
斐波那契数列在递归的学习时经常被拿来做例子,当剑指offer上看到这个题的时候,我就直接用递归写了,然后发现了问题,调用栈空间太多。这就是递归方法的一个缺陷,虽然简单容易理解,然而效率上却为难了计算机。所以还是以循环来实现:
long long Fibonacci(unsigned int n) { int result[2] = {0,1}; if(n < 2) return result[n]; // 当n>2时 long long first = 1; long long second = 0; long long fib = 0; for(unsigned int i = 2; i <= n; ++i) { fib = first + second; second = first; first = fib; } return fib; }
其实斐波那契数列的循环实现很容易写出来,就根据斐波那契的定义来写就好了:第n项为其前两项的和,只要从头开始求每一项向后推就可以得到结果。
变形1:下边是斐波那契数列的一个变形,青蛙跳台阶。
- 题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
-
分析:
其实和斐波那契函数是一个道理,如果一次它想跳到第n级台阶,因为一次只能跳一级或者两级,所以它一定是从第n-1级台阶,或者是n-2级台阶跳上来的,所以可以分解为求f(n-1)+f(n-2)。
代码:class Solution { public: int jumpFloor(int n) { int result[2] = {1,2}; if(n < 3 && n > 0) return result[n-1]; int first = 2; int second = 1; int fib = 0; for(int i = 3; i <= n; ++i){ fib = first + second; second = first; first = fib; } return fib; } };
变形2:
- 题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
-
分析:
我这种凡人,只想到了凡人的方法。。
每个台阶都可以直接跳上去,也可以从前边每个台阶跳上来。所以每个台阶的可能性都是把其前边所有台阶的可能性加起来,再加1(就是直接跳上去的可能性)。f(n) = f(n-1)+f(n-2)+f(n-3)+...+f(1)+1;
f(n-1) = f(n-2)+f(n-3)+f(n-4)...+f(1)+1
两式相减,得到f(n) = 2f(n-1);
好吧,等比数列,f(n) = 2^(n-1)接下来是牛客上看到的,大神的思路:
每个台阶都有跳与不跳两种情况(除了最后一个台阶),最后一个台阶必须跳。所以共用2^(n-1)中情况
不得不说言简意赅,跟我等找规律的不一样。
再接下来是代码,我的思路:
class Solution { public: int jumpFloorII(int number) { if(number > 0){ // 用一个长度为number的vector把每一级台阶的可能性都记录下来 vector<int> v(number,0); v[0]=1; // 每个台阶都是把其前边所有台阶的可能性加起来再加一 for(int i = 1; i < number; ++i){ for(int j = 0; j < i; ++j){ v[i] += v[j]; } ++v[i]; } return v[number-1]; } else return 0; } };
又有一行代码解决问题的大神:
// 1左移number-1位,即2^(number-1) return 1 << --number;
变形3:
- 题目描述:
我们可以用2x1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2x1的小矩形无重叠地覆盖一个2xn的大矩形,总共有多少种方法?
-
分析:
举例观察可知还是斐波那契
class Solution { public: int rectCover(int number) { if(number < 1) return 0; int result[2] = {1,2}; if(number < 3) return result[number-1]; int first = 2; int second = 1; int num = 0; for(int i = 3; i <= number; ++i){ num = first + second; second = first; first = num; } return num; } };