当前位置:   article > 正文

力扣70. 爬楼梯(递归、动态规划、斐波那契数列)_递归爬楼梯复杂度

递归爬楼梯复杂度

力扣70. 爬楼梯

https://leetcode-cn.com/problems/climbing-stairs/

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 阶 + 1 阶
2.  2 阶
示例 2:

输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 阶 + 1 阶 + 1 阶
2.  1 阶 + 2 阶
3.  2 阶 + 1 阶

 

方法:递归、动态规划、斐波那契数列

  1. #include "stdafx.h"
  2. #include <vector>
  3. #include <iostream>
  4. using namespace std;
  5. class Solution
  6. {
  7. public:
  8. //递归,超时
  9. int climbStairsrecursive(int n)
  10. {
  11. int k = 0;
  12. //递归
  13. recursive(n,k);
  14. return k;
  15. }
  16. void recursive(int x, int &k)
  17. {
  18. //递归终止
  19. if (x == 0)
  20. {
  21. k++;
  22. return;
  23. }
  24. //跳1级
  25. if (x - 1 >= 0)recursive(x - 1,k);
  26. //跳2级
  27. if (x - 2 >= 0)recursive(x - 2,k);
  28. }
  29. //动态规划
  30. int climbStairsdynamic(int n)
  31. {
  32. vector<int>result;
  33. result.push_back(1); result.push_back(1);
  34. int i = 2;
  35. while (n >= i)
  36. {
  37. //到达第 i 阶的方法总数就是到第 (i-1) 阶和第 (i-2) 阶的方法数之和
  38. int temp = result[i - 1] + result[i - 2];
  39. result.push_back(temp);
  40. i++;
  41. }
  42. return result[n];
  43. }
  44. //斐波那契数Fibonacci sequence
  45. //思路和动态规划一样,只不过空间复杂度:O(1)使用常量级空间
  46. int climbStairsfib(int n)
  47. {
  48. int f = 0;
  49. int g = 1;
  50. int i = 1;
  51. while (n >= i)
  52. {
  53. //到达第 i 阶的方法总数就是到第 (i-1) 阶和第 (i-2) 阶的方法数之和
  54. g = f + g;
  55. f = g - f;
  56. i++;
  57. }
  58. return g;
  59. }
  60. };
  61. int main()
  62. {
  63. Solution s;
  64. for (int i=0;i<=30;i++)
  65. {
  66. auto resultrecursive = s.climbStairsrecursive(i);
  67. auto resultdynamic = s.climbStairsdynamic(i);
  68. auto resultfib = s.climbStairsfib(i);
  69. cout << i << "递归:" << resultrecursive << '\t' << "动态规划:" << resultdynamic << '\t' << "斐波那契数:" << resultfib<<'\n';
  70. if ((resultrecursive != resultdynamic) || (resultrecursive != resultfib))
  71. {
  72. cout << '\n' << '\n' << "error" << '\n' << '\n';
  73. break;
  74. }
  75. }
  76. return 0;
  77. }

一、递归

复杂度分析

  • 时间复杂度:O(2^n),树形递归的大小为 2^n    所以会超时

  • 空间复杂度:O(n),递归树的深度可以达到 n

  • 在 n = 5 时的递归树将是这样的:

Climbing_Stairs

上图来源力扣官方解析:https://leetcode-cn.com/problems/climbing-stairs/solution/pa-lou-ti-by-leetcode/

  1. //递归,超时
  2. int climbStairsrecursive(int n)
  3. {
  4. int k = 0;
  5. //递归
  6. recursive(n,k);
  7. return k;
  8. }
  9. void recursive(int x, int &k)
  10. {
  11. //递归终止
  12. if (x == 0)
  13. {
  14. k++;
  15. return;
  16. }
  17. //跳1级
  18. if (x - 1 >= 0)recursive(x - 1,k);
  19. //跳2级
  20. if (x - 2 >= 0)recursive(x - 2,k);
  21. }

二、动态规划

复杂度分析

  • 时间复杂度:O(n),单循环到 n 。

  • 空间复杂度:O(n),dp 数组用了 n 的空间。

思路:

第 i 阶可以由以下两种方法得到:

在第 (i-1)阶后向上爬1阶。

在第 (i-2)阶后向上爬 2 阶。

所以到达第 i 阶的方法总数就是到第 (i-1)阶和第 (i-2)阶的方法数之和。

  1. //动态规划
  2. int climbStairsdynamic(int n)
  3. {
  4. vector<int>result;
  5. result.push_back(1); result.push_back(1);
  6. int i = 2;
  7. while (n >= i)
  8. {
  9. //到达第 i 阶的方法总数就是到第 (i-1) 阶和第 (i-2) 阶的方法数之和
  10. int temp = result[i - 1] + result[i - 2];
  11. result.push_back(temp);
  12. i++;
  13. }
  14. return result[n];
  15. }

三、斐波那契数列

Fib(n)=Fib(n−1)+Fib(n−2)

 

Fib(0)=1,Fib(1)=1,Fib(2)=2,

复杂度分析

  • 时间复杂度:O(n),单循环到 n,需要计算第 n 个斐波那契数。

  • 空间复杂度:O(1),使用常量级空间。

  1. //斐波那契数Fibonacci sequence
  2. //思路和动态规划一样,只不过空间复杂度:O(1)使用常量级空间
  3. int climbStairsfib(int n)
  4. {
  5. int f = 0;
  6. int g = 1;
  7. int i = 1;
  8. while (n >= i)
  9. {
  10. //到达第 i 阶的方法总数就是到第 (i-1) 阶和第 (i-2) 阶的方法数之和
  11. g = f + g;
  12. f = g - f;
  13. i++;
  14. }
  15. return g;
  16. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/559055
推荐阅读
相关标签
  

闽ICP备14008679号