n 个台阶的走法就是先走一步之后n-1个台阶的走法,加上先走两步之后n-2个台阶的走法:
f[n] = f(n-1) + f(n-2)
f[1] = 1, f[0] = 1
递归
递归代码逻辑很简单,但是不幸超时了。。。
class Solution {
public:
int climbStairs(int n) {
//if(n == 0 || n == 1) return 1;
return n < 2 ? 1 : climbStairs(n-1) + climbStairs(n-2);
}
};
超时的原因应该是递归太深导致堆栈溢出,或者是产生了大量重复计算导致效率降低,解决方法一般就是记忆化避免重复计算或者动态规划。
记忆化递归
class Solution {
public:
vector<int> memo;
int climbStairs(int n) {
if(memo.empty()) memo = vector<int>(n+1, 0);
if(n == 0 || n == 1) return 1;
if(memo[n]) return memo[n];
int ret = climbStairs(n-1) + climbStairs(n-2);
memo[n] = ret;
return ret;
}
};
class Solution {
public:
vector<int> memo = vector<int>(100, 0);
int climbStairs(int n) {
if(n < 4) return n;
if(memo[n]) return memo[n];
int ret = climbStairs(n-1) + climbStairs(n-2);
memo[n] = ret;
return ret;
}
};
动态规划
class Solution {
public:
int climbStairs(int n) {
if(n < 3) return n; //n < 4也行
int last = 1, cur = 2, pre;//分别表示之前、当前以及下一个要计算的状态
for(int i = 3; i <= n; ++i){
pre = last + cur;
last = cur;
cur = pre;
}
return cur;
}
};