斐波那契數列
最簡單的遞歸法:
存在大量的重疊子問題,時間複雜度爲 ,很慢,會超時。
class Solution {
public:
int Fibonacci(int n) {
if(n==0 or n==1) return n;
return Fibonacci(n-1) + Fibonacci(n-2);
}
};
動態規劃: 直接從子樹求得答案,過程是從下往上,時間複雜度:O(n),空間複雜度:O(n)
class Solution {
public:
int Fibonacci(int n) {
if(n==0 or n==1) return n;
int a{0}, b{1}, c;
for(int i=2; i<=n; i++){
c = a + b;
a = b;
b = c;
}
return c;
}
};
青蛙跳臺階
題目描述:
一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法(先後次序不同算不同的結果)。
分析:
假設 表示跳上第 個臺階的方法數,而第n個臺階可以是由第n-1個臺階跳上的,也可以是由第n-2個臺階跳上的,所以方法數 ,且初始條件 f[1] = 1,f[2] = 2. 本質上還是斐波那契數列。不再附代碼了。
變態跳臺階
題目描述:
一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
分析:
假設 表示跳上第 個臺階的方法數,求 。
假設現在已經跳到了第 n 個臺階,那麼前一步可以從哪些臺階到達呢?
- 如果上一步跳 1 步到達第 n 個臺階,說明上一步在第 n-1 個臺階,而跳到第n-1個臺階的方法數爲f[n-1];
- 如果上一步跳 2 步到達第 n 個臺階,說明上一步在第 n-2 個臺階,而跳到第n-2個臺階的方法數爲f[n-2];
- 。。。
- 如果上一步跳 n-1 步到達第 n 個臺階,說明上一步在第 1 個臺階。已知跳到 第1個臺階的方法數爲f[1] = 1
- 如果上一步跳 n 步到達第 n 個臺階,說明上一步在第 0 個臺階。已知跳到 第0個臺階的方法數爲f[0] = 0
那麼總的方法數就是所有可能的和:f[n] = f[n-1] + f[n-2] + … + f[1]
顯然初始條件還是 f[1] =1, f[2] = 2
繼續分析:
f[n] = f[n-1] + f[n-2] + … + f[1], 那麼 f[n-1] 呢?
顯然,f[n-1] = ff[n-2] + … + f[1]
原來如此:f[n] = f[n-1] × 2
繼續分析:
累乘法:
f[n] = f[n-1] × 2
f[n-1] = f[n-2] × 2
…
f[3] = f[2] × 2 = 2 × 2
所以:f[n] = pow(2, n-1)
return pow(2, n-1);
return 1 << (n-1);