1 /*
2 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
3 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
4
5 示例 1:
6 输入:n = 2
7 输出:2
8 解释:有两种方法可以爬到楼顶。
9 1. 1 阶 + 1 阶
10 2. 2 阶
11
12 示例 2:
13 输入:n = 3
14 输出:3
15 解释:有三种方法可以爬到楼顶。
16 1. 1 阶 + 1 阶 + 1 阶
17 2. 1 阶 + 2 阶
18 3. 2 阶 + 1 阶
19 */
20
21 // 方法一:递归方法,类似递归形式的斐波那契数列,时间复杂度:O(2**n),空间复杂度:O(n)
22
23 // 方法二:记忆化递归方法,时间复杂度:O(n),O(n)
24 #include <iostream>
25 #include <cstdio>
26 using namespace std;
27
28 int climbStairsMemo(int n, int memo[]) {
29 if (memo[n] > 0) {
30 return memo[n];
31 }
32 if (n == 1) memo[n] = 1;
33 else if (n == 2) memo[n] = 2;
34 else memo[n] = climbStairsMemo(n - 1, memo) + climbStairsMemo(n - 2, memo);
35 return memo[n];
36 }
37
38 int climbStairs2(int n) {
39 int memo[n + 1];
40 return climbStairsMemo(n, memo);
41
42 }
43
44
45 // 方法三:动态规划,时间复杂度:O(n),O(n)
46 int climebStairs3(int n) {
47 if (n == 1) return 1;
48 int dp[n + 1];
49 dp[1] = 1;
50 dp[2] = 2;
51
52 for (int i = 3; i <= n; i++) {
53 dp[i] = dp[i - 1] + dp[i - 2];
54 }
55
56 return dp[n];
57 }
58
59 // 方法四:
60 /*
61 可以发现,方法三在计算 dp[i] 时,实际上只需要用到 dp[i - 1] 和 dp[i - 2] 的值,并不需要存储整个数组 dp。
62 因此,可以使用常数级的额外空间来优化这段代码,将空间复杂度降低到 O(1)。以下是优化后的代码:
63 */
64 int climbStairs4(int n) {
65 if (n == 1) return 1;
66 int first = 1;
67 int second = 2;
68 int third;
69
70 for (int i = 3; i <= n; i++) {
71 third = first + second;
72 first = second;
73 second = third;
74 }
75
76 return second;
77 }
78
79 int main() {
80
81
82
83 return 0;
84 }