题目一:求斐波那契数列的第 n 项
写一个函数,输入n,求斐波那契(Fibonacci)数列的第 n 项。
解法一:递归
public static int Fibonacci(int n) {
if(n <= 0) return 0;
if(n == 1) return 1;
return Fibonacci(n-1) + Fibonacci(n-2);
}
这道题用递归会存在非常严重的效率问题,重复计算很严重:
解法二(较优解法):循环,且从小往大算
public static int Fibonacci(int n) {
if(n <= 0) return 0;
if(n == 1) return 1;
int min1 = 0;
int min2 = 1;
int result = 0;
for(int i = 2; i <= n; i++) {
result = min1 + min2;
min1 = min2;
min2 = result;
}
return result;
}
题目二:青蛙跳台阶问题
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个n级台阶总共有多少种跳法。
解法一:递归
public static void frogJump(int cur, int n) {
if(cur == n) {
count++;
return;
} else if(cur > n) {
return;
}
else {
frogJump(cur+1, n);
frogJump(cur+2, n);
}
}
解法二:跳到第n级台阶之前,青蛙可能在第n-1级台阶和第n-2级台阶,所以,f(n) = f(n-1) + f(n-2)。所以,这个题也是求解斐波那契数列问题
public static int frogJump(int n) {
if(n <= 0) return 0;
if(n == 1) return 1;
if(n == 2) return 2;
int min1 = 1, min2 = 2;
int result = 0;
for(int i = 3; i <= n; i++) {
result = min1 + min2;
min1 = min2;
min2 = result;
}
return result;
}
扩展题
我们可以用 2 × 1 的小矩形横着或竖着去覆盖更大的矩形,请问用 8 个 2 × 1 的小矩形无重叠地去覆盖一个 2 × 8 的大矩形,总共有多少种方法?
思路:
放第一块的时候,可以横着放或者竖着放:
- 如果竖着放,则还剩 2 × 7 的矩形,有 f(7)次可能
- 如果横着放,例如放在左上角,那么左下角必然要放一块,这样就还有 f(6) 种可能。
也就是说,这道题,还是可以通过斐波那契数列来求解。