斐波那契数列
用递归实现斐波那契数列的复杂度分析:
时间复杂度:O(2n)。在递归计算过程中,会产生大量的重复计算。例如,计算 F(n) 时需要计算
F(n?1) 和 F(n?2),而计算 F(n?1) 时又会计算 F(n?2),以此类推,形成了一个指数级的递归树,
节点数随着 n 的增大呈指数级增长。
空间复杂度:O(n)。递归调用会使用系统栈空间,递归的深度最大为 n,所以空间复杂度为 O(n)。
详细解释可以参考视频:https://www.bilibili.com/video/BV1JrWoe1EhW?t=82.5
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 using namespace std; 5 // 用递归的方式来求斐波那契数列 6 int Fibonacci1(int n) { 7 if (n == 0) { 8 return 0; 9 } else if (n == 1) { 10 return 1; 11 } else { 12 return Fibonacci1(n - 2) + Fibonacci1(n - 1); 13 } 14 } 15 16 vector<int> FibonacciArray(int m) { 17 vector<int> result; 18 int k = 0; 19 int currentFib = Fibonacci1(k); 20 while (currentFib <= m) { 21 result.push_back(currentFib); 22 k++; 23 currentFib = Fibonacci1(k); 24 } 25 return result; 26 } 27 28 int main() { 29 int n = 1e8; 30 31 // printf("请输入数n(n>=0):"); 32 // scanf("%d", &n); 33 34 double beginTime = clock(); 35 printf("小于等于%d的斐波那契数列是:", n); 36 for (int num : FibonacciArray(n)) { 37 cout << num << " "; 38 } 39 double endTime = clock(); 40 printf("\ntime=%.0lfms", endTime - beginTime); 41 42 return 0; 43 }
动态规划方式通过迭代的方法,从斐波那契数列的前两项开始,依次计算后续的项,
并将结果存储在一个数组中,避免了递归方式中的重复计算。
复杂度分析
时间复杂度:O(k),其中 k 是满足斐波那契数列第 k 项大于指定上限 n 的最小 k 值。
在迭代过程中,只需要遍历一次来计算每一项,每次计算的时间为常数时间,
所以总的时间复杂度与需要计算的斐波那契数的个数成正比。
空间复杂度:O(k)。主要的空间开销是用于存储斐波那契数列中小于等于n 的所有项的数组,
数组的长度为 k
时间复杂度视频讲解:https://www.bilibili.com/video/BV1kWHPebEFu?t=79.0
动态规划的核心三要素,我们可以用斐波那契数列为例详细解释,
可以参考同目录下的 "动态规划核心三要素.txt" 文件
1. 最优子结构:大问题最优解包含子问题最优解
2. 重叠子问题:子问题被重复计算(可用记忆化优化)
3. 状态转移方程:递推关系的数学表达
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 using namespace std; 5 // 用动态规划的方式来求斐波那契数列 6 vector<int> Fibonacci(int n) { 7 vector<int> fib; 8 int k = 1; 9 fib.push_back(0); 10 fib.push_back(1); 11 while (fib[k] <= n) { 12 k++; 13 fib[k] = fib[k - 1] + fib[k - 2]; 14 if (fib[k] <= n) fib.push_back(fib[k]); 15 } 16 17 return fib; 18 } 19 20 21 int main() { 22 int n = 1e8; 23 24 // printf("请输入数n(n>=0):"); 25 // scanf("%d", &n); 26 27 double beginTime = clock(); 28 printf("小于等于%d的斐波那契数列是:", n); 29 for (int num : Fibonacci(n)) { 30 cout << num << " "; 31 } 32 double endTime = clock(); 33 printf("\ntime=%.0lfms", endTime - beginTime); 34 35 return 0; 36 }

浙公网安备 33010602011771号