面試題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);
}
}
複製代碼