You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.
Example 1:
Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps
Example 2:
Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step
这道题和杨辉三角、斐波那契数列是同一类型的题,都是当前结果需要“前面”两个结果来得到。
不过,从实际题目抽象出来算法,我刚开始一直转不过弯来,即便是看到思路是:当前N的结果是N-1结果加N-2结果,依旧不知道是什么意思,就是转不过这个弯,人有时就是这样。其实从实际考虑也很好理解,现在N-1知道多少条路了,只要走1步就能到达N了,N-2知道多少条路了,只要走2步就能到达N了,所以算法是N的结果是N-1的结果加N-2的结果。
最基本的算法,递归:
class Solution {
public int climbStairs(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
if(n == 2) return 2;
return climbStairs(n-1) + climbStairs(n-2);
}
}
这类问题是属于动态规划问题,上面的解法,中间过程结果会重复计算,故采用memoization技术进行优化
class Solution {
int[] store;
public int climbStairs(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
store = new int[n+1];
store[0] = 0;
store[1] = 1;
store[2] = 2;
return helper(n);
}
private int helper(int n) {
if(n == 0) return store[0];
if(store[n] != 0) return store[n];
store[n] = helper(n-1) + helper(n-2);
return store[n];
}
}
上面的解法,我们可以理解为是top-down的DP解法,我们也可以采用DP的bottom-up解法
class Solution {
public int climbStairs(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
int[] store = new int[n+1];
store[1] = 1;
store[2] = 2;
for(int i = 3; i <= n; i++) {
store[i] = store[i-1] + store[i-2];
}
return store[n];
}
}