假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
3. 1 阶 + 1 阶 + 1 阶
4. 1 阶 + 2 阶
5. 2 阶 + 1 阶
思路1:推算便知 是斐波那契数列的变形 爬楼梯数列满足:1 2 3 5 8… 斐波那契数列是: 1 1 2 3 5 8…
多一项1。可以用数组形式迭代实现。其中ans[0]是为了配凑斐波那契数列的形式,真正要求的是数组的第n项,也就是序列的第n+1个(因为前面补了一项ans[0])
class Solution {
public:
int climbStairs(int n) {
if(n<2){
return 1;
}
int ans[n+1]={0};
ans[0]=1;
ans[1]=1;
for(int i=1;i<n;++i){
ans[i+1]=ans[i]+ans[i-1];
}
return ans[n];
}
};
思路2:递归实现:
我自己写的递归 运行错误 考虑错误是因为:第一个return 2 之后 把n的值修改成了2 所以当输入为n=3时 输出为4
class Solution {
public:
int climbStairs(int n) {
if(n<3){
return n==2?2:1;
}
else
return climbStairs(n-1)+climbStairs(n-2);
}
};
修改后:思路是对的 可是运行超时 看评论中解释是因为:
这种方法会有太多的重复计算,比如要计算climbStairs(n)需要计算climbStairs(n-1)和climbStairs(n-2)
但是求climbStairs(n-1)还要计算climbStairs(n-2)和climbStairs(n-3) 如此一来climbStairs(n-2)被计算了两遍
如此一来 运行到结束会有大量重复运算。
解决方法是通过一个map记录下来已经计算出来的值,每次计算前都去map里get一下,再把当前值存入map
class Solution {
public:
int climbStairs(int n) {
if(n==1)
return 1;
else if(n==2)
return 2;
else
return climbStairs(n-1)+climbStairs(n-2);
}
};
思路三:敲了一下大神的题解,如此简短
class Solution {
public:
int climbStairs(int n) {
int a=0,b=1,c=0;
while(n--){
c=a+b;
a=b;
b=c;
}
return c;
}
};
思路四:使用公式直接计算 省略
思路五:带有记忆的递归 没看懂