70. 爬楼梯,记忆递归以及递归的几个等价写法
问题
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶
分析
dp入门题,递归,记忆递归,递推。
一、递推
class Solution {
public:
int f[50];
int climbStairs(int n) {
f[0] = 1;
f[1] = 1;
for (int i = 2; i <= n; i++) {
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
};
二、递归,超时,21/45
class Solution {
public:
int dfs(int x) {
if (x == 0 || x == 1) {return 1;}
return dfs(x-1) + dfs(x-2);
}
int climbStairs(int n) {
return dfs(n);
}
};
三、记忆递归
class Solution {
public:
int mem[50];
int dfs(int x) {
if (mem[x] != -1) {return mem[x];}
if (x == 0 || x == 1) {return 1;}
int s = 0;
s = dfs(x-1) + dfs(x-2);
mem[x] = s;
return s;
}
int climbStairs(int n) {
memset(mem, -1, sizeof mem);
return dfs(n);
}
};
递归改为记忆递归的方法:
- 在递归出口前后各加一句、之后的都赋值s、s赋值记忆数组、返回s
补充几个递归的写法,加深理解
对于每个子状态的结果,可以用返回值,参数,全局变量来记录,三种方法等价。返回值最简单,其他的这里给出写法。
- 不带返回值的递归
class Solution {
public:
void dfs(int x, int& ans) { // 注意这里是引用
if (x == 0 || x == 1) {ans = 1; return ;}
int a = 0, b = 0;
dfs(x-1, a);
dfs(x-2, b);
ans = a+b;
}
int climbStairs(int n) {
memset(f, -1, sizeof f);
int res = 0;
dfs(n, res);
return res;
}
};
- 全局变量
class Solution {
public:
int res = 0;
void dfs(int x) {
if (x == 0 || x == 1) {res = 1; return ;}
int a = 0, b = 0;
dfs(x-1); a = res;
dfs(x-2); b = res;
res = a+b;
}
int climbStairs(int n) {
dfs(n);
return res;
}
};
综上,还是返回值更好理解。

浙公网安备 33010602011771号