题目
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
1 2 3 4 5
| 输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。 1. 1 阶 + 1 阶 2. 2 阶
|
示例 2:
1 2 3 4 5 6
| 输入: 3 输出: 3 解释: 有三种方法可以爬到楼顶。 1. 1 阶 + 1 阶 + 1 阶 2. 1 阶 + 2 阶 3. 2 阶 + 1 阶
|
思路
- 最简单的思路, 用递归的思想解决. 爬3层楼梯可以看成爬2层+1层问题的方法集合, 终止条件就是当n计算到1
- 因为存在大量重复计算, 所以可以用HashMap或者数组存储中间结果
- 当然也可以不用递归, 直接迭代计算
代码实现
1 2 3 4 5 6 7 8 9
| public int climbStairs(int n) { if(n <= 1) { return 1; } if(n == 2) { return 2; } return climbStairs(n - 1) + climbStairs(n-2); }
|
但是这种实现时间复杂度是O(n2), 有很多重复计算, 导致运行时间过长.
所以考虑缓存中间运算结果, 用HashMap或者数组都可以, 在这里用了数组来保存.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public int climbStairs(int n) { int[] cache = new int[n + 1]; return climbStairsWithCache(n, cache); }
private int climbStairsWithCache(int n, int[] cache) { if (cache[n] != 0) { return cache[n]; } if (n == 1) { cache[n] = 1; return 1; } if (n == 2) { cache[n] = 2; return 2; } int func2 = climbStairsWithCache(n - 2, cache); cache[n - 2] = func2; int func1 = climbStairsWithCache(n - 1, cache); cache[n - 1] = func1; return func2 + func1; }
|
1 2 3 4 5 6 7 8 9
| public int climbStairs(int n) { int p = 0, q = 0, r = 1; for (int i = 1; i <= n; ++i) { p = q; q = r; r = p + q; } return r; }
|