LeetCode509(力扣509) :斐波那契數列 C++ 多種思路與詳細解析
509 斐波那契數列
斐波那契數,通常用 F(n) 表示,形成的序列稱為斐波那契數列。該數列由 0 和 1 開始,後面的每一項數字都是前面兩項數字的和。也就是:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
給定 N,計算 F(N)。
示例 1:
輸入:2
輸出:1
解釋:F(2) = F(1) + F(0) = 1 + 0 = 1.
示例 2:
輸入:3
輸出:2
解釋:F(3) = F(2) + F(1) = 1 + 1 = 2.
示例 3:
輸入:4
輸出:3
解釋:F(4) = F(3) + F(2) = 2 + 1 = 3.
提示:
0 ≤ N ≤ 30
我的提交程式碼:
class Solution {
public:
int fib(int N) {
if (N == 0) return 0;
if (N == 1) return 1;
return fib(N - 1) + fib(N - 2);
}
};
我的思想
沒有思想這個題,學習遞迴的必會程式碼啊!都不需要寫測試程式碼,直接提交就好啦~提交是能通過,但是同時拿去提交別的斐波那契題的時候就不行拉,會超時。因為這是遞迴,會重複計算很多沒有用的數,因此接下來要去學習優化的程式碼。
畫出遞迴樹:
可以看出會重複一些fib(n)的值,使得演算法的效率變低
子問題的個數為: 遞迴樹中節點的總數,由樹的特徵可以得到遞迴計算斐波那契數列的時間複雜度為O(2^n)爆炸拉成指數增長。
官方題解二:記憶化自底向上的方法
自底向上通過迭代計算斐波那契數的子問題並儲存已計算的值,通過已計算的值進行計算。減少遞迴帶來的重複計算。
演算法:
- 如果 N 小於等於 1,則返回 N。
- 迭代 N,將計算出的答案儲存在陣列中。
- 使用陣列前面的兩個斐波那契數計算當前的斐波那契數。
- 計算到 N,則返回它的斐波那契數。
class Solution {
public:
int fib(int N) {
if (N <= 1) {
return N;
}
return memoize(N);
}
public:
int memoize(int N) {
vector<int> temp(N+1);
temp[0] = 0;
temp[1] = 1;
for (int i = 2; i <= N; i++) {
temp[i] = temp[i - 1] + temp[i - 2];
}
return temp[N];
}
};
由此兩種方法的執行用時可以明顯看到演算法效率的優化。此種演算法以空間換了時間,新開闢了一個N+1的陣列來儲存在每一個fib(n)時候的值。此時的空間複雜度為O(n+1)
此處又可以對空間進行優化了,那麼我們每一次計算其實只需要n前面的兩個數而已,反正也是從底向頂,最後要計算n的斐波那契數為多少,因為底部算過的數對我們之後並沒有用,我們可以建立3個變數然後不斷覆蓋就能節省空間了。
class Solution {
public:
int fib(int N) {
if (N <= 1) {
return N;
}
return memoize(N);
}
public:
int memoize(int N) {
int sum = 0;
int first = 0;
int second = 1;
for (int i = 2; i <= N; i++) {
sum = first + second;
first = second;
second = sum;
}
return sum;
}
};
可以顯然的看到,記憶體消耗有明顯的減低。此時的空間複雜度為O(1)
我學會拉
- 能不用遞迴,別用遞迴,複雜度爆炸!
- 分析子問題,可以用迴圈迭代來解決問題。
- 在解出一個問題後,要多思考如何操作能使得程式碼效率更高。例如此題,用過一次就不用的記憶體空間,我們可以考慮少申請,不斷覆蓋。
相關文章
- 力扣之斐波那契數列力扣
- 509. 斐波那契數
- LeetCode 509[斐波那契數]LeetCode
- LeetCode-509-斐波那契數LeetCode
- 斐波那契數列詳解
- 2021-01-04 509.斐波那契數列
- PHP 與斐波那契數列PHP
- 斐波那契數列
- 【LeetCode刷題】509. 斐波那契數LeetCode
- 斐波那契數列(Java)Java
- LeetCode每日一題:斐波那契數(No.509)LeetCode每日一題
- 斐波那契數列數與等冪和
- 斐波那契數列 (C#)C#
- 著名的斐波那契數列
- 斐波那契數
- 斐波那契數列三種實現函式函式
- js實現斐波那契數列JS
- 斐波那契數列演算法演算法
- 第十題:斐波那契數列
- [C103] 斐波那契數列
- 劍指offer——斐波那契數列
- 斐波那契數列js 實現JS
- 斐波那契數列Ⅳ【矩陣乘法】矩陣
- 斐波那契數列 多語言實現 筆記筆記
- 使用Python實現斐波那契數列Python
- 演算法(1)斐波那契數列演算法
- 斐波那契數列的來源——數兔子
- fibonacci斐波那契數列詳解 遞迴求Fn非遞迴求Fn求n最近的斐波那契數遞迴
- 2024.9.6 leetcode 509 斐波那契數 (雜湊表/動態規劃)LeetCode動態規劃
- Leedcode-斐波那契數
- 一千位斐波那契數
- 大數斐波那契數列的演算法演算法
- js迭代器實現斐波那契數列JS
- offer通過--9斐波那契數列-2
- 演算法一:斐波那契阿數列演算法
- JavaScript 實現:輸出斐波那契數列JavaScript
- 斐波那契數列魔法塔數字量與層數的關係
- 斐波那契數列:7數5層魔法塔(3)