面试题9:你们都知道斐波那契数列,如今要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39面试
当 0 < n <= 1 时,f(n) = n;
当 n > 1 时,f(n) = f(n-1) + f(n-2)
复制代码
1、递归写法(低效,慢)bash
递归分析,以下图所示:ui
这棵树中有不少结点是重复的,并且重复的结点数会随着n的增大而急剧增长,这意味计算量会随着n的增大而急剧增大。spa
用递归方法计算的时间复杂度是以n的指数的方式递增的。code
2、for 循环写法cdn
使用中间变量,在每次循环以后都将中间计算结果保存起来,用于下一次循环,时间复杂度减小到O(n)。blog
1、递归写法(低效,慢)递归
public class Solution {
public int Fibonacci(int n) {
if(n <= 1) {
return n;
}
return Fibonacci(n-1) + Fibonacci(n-2);
}
}
复制代码
2、for 循环写法ci
public class Solution {
public int Fibonacci(int n) {
if(n <= 1) {
return n;
}
int fibNMinus1 = 1;
int fibNMinus2 = 0;
int fibN = 0;
for(int i=2; i<=n; i++){
fibN = fibNMinus1 + fibNMinus2;
fibNMinus2 = fibNMinus1;
fibNMinus1 = fibN;
}
return fibN;
}
}
复制代码
递归实现起来简洁,但一般效率比for循环要低不少。get
题目:一只青蛙一次能够跳上1级台阶,也能够跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(前后次序不一样算不一样的结果)。
前提只有 一次 1阶或者2阶的跳法。
a.若是两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);
b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)
c.由a和b 两种假设能够得出总跳法为: f(n) = f(n-1) + f(n-2)
d.Base case:只有一阶的时候 f(1) = 1 ,只有两阶的时候能够有 f(2) = 2
复制代码
public class Solution {
public int JumpFloor(int target) {
if(target <= 0) {
return -1;
}
if(target <= 2){
return target;
}
return JumpFloor(target - 1) + JumpFloor(target - 2);
}
}
复制代码
题目:一只青蛙一次能够跳上1级台阶,也能够跳上2级……它也能够跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
数学概括法,各类计算,略过。
题目:咱们能够用2×1(图2.13的左边)的小矩形横着或者竖着去覆盖更大的矩形。请问用8个2×1的小矩形无重叠地覆盖一个2×8的大矩形(图2.13的右边),总共有多少种方法?
首先把 2x8 的覆盖方法总数记为 f(8)。
用第一个 1x2 小矩形去覆盖大矩形的最左边时有两个情形,竖着放或者横着放。
竖着放:右边还剩下 2x7 的区域,这种情形下的覆盖方法记为 f(7)。
横着放:1x2 小矩形无论是横着放在左上角仍是左下角,另一个小矩形必须跟在该小矩形的下边或上边贴合,即不管如何只有
一种覆盖方法。而此时右边还剩下 2x6 的区域,这种情形下的覆盖方法记为 f(6)。
2x8 的覆盖方法就由这两种情形构成,所以,他们之间存在如下关系:
f(8) = f(7) + f(6)
类推:f(n) = f(n-1) + f(n-2) 即斐波那契数列。
复制代码
public class Solution {
public int RectCover(int target) {
if(target<=2) {
return target;
}
return RectCover(target - 1) + RectCover(target - 2);
}
}
复制代码