
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 }