原理视频讲解
录制了一个小视频投放至B站,看文章不理解的小伙伴现在可以看视频啦,B站中用Java代码实现该算法,提供一个不同的理解视角:
https://www.bilibili.com/video/BV1uA411g7aY/
自顶向下的备忘录优化算法
#include <iostream>
#include "vector"
using namespace std;
int helper(int N, vector<int>& memo);
int fib(int N)
{
if (N == 0) return 0;
vector<int> memo(N+1, 0);
return helper(N, memo);
}
int helper(int N, vector<int>& memo)
{
if (N == 1 || N == 2) return 1;
if (memo[N] != 0) return memo[N];
memo[N] = helper(N - 1, memo) + helper(N - 2, memo);
return memo[N];
}
int main() {
int N = 20;
int res = fib(N);
cout << res << endl; // 6765
return 0;
}
自底向上的dp数组解法
#include <iostream>
#include "vector"
using namespace std;
int fib(int n){
if (n == 0) return 0;
vector<int> dp(n + 1, 0);
dp[1] = dp[2] = 1;
for (int i = 3; i <= n; ++i) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
int main() {
int N = 20;
int res = fib(N);
cout << res << endl; // 6765
return 0;
}
上述代码的空间复杂度为O(N),因为斐波那契数列的某一个数的计算并不需要将此前的整个数列都记录下来,因此可以做如下进一步优化,使得空间复杂度为O(1):
int fib(int n){
if (n == 0) return 0;
if (n == 1 || n == 2) return 1;
int pres, curr;
pres = curr = 1;
for (int i = 3; i <= n; ++i) {
int res = pres + curr;
pres = curr;
curr = res;
}
return curr;
}