假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
思路
最简单的思路是回溯。但是效率太差,重复计算太多,会严重超时。
class Solution {
public:
int climbStairs(int n) {
if (n == 1 || n == 2)
return n;
return climbStairs(n - 1) + climbStairs(n - 2);
}
};
规律:
因为每次只能爬1/2步没所以:第 i 阶的爬法数量=第i-1阶的爬法数量+第i-2阶的爬法数量。
- 设置递推数组dp[0...n],dp[i]代表到达第i阶,有多少种走法,初始化数组元素为0.
- 设置到达第1阶台阶,有1种走法;到达第2阶套机,有两种走法。
- 利用i循环递推从第3阶至第n阶的结果:
- 第 i 阶的爬法数量=第i-1阶的爬法数量+第i-2阶的爬法数量。
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <stack>
#include <set>
#include <queue>
#include <algorithm> //标准算法的头文件
using namespace std;
class Solution {
public:
int climbStairs(int n) {
vector<int> dp(n+3, 0); //需要为dp[0、1、2]留位置
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++)
dp[i] = dp[i - 1] + dp[i - 2];
return dp[n];
}
};
void test02() {
Solution s;
cout << s.climbStairs(10) << endl;
}
int main() {
test02();
system("pause");
return 0;
}
class Solution {
public:
int climbStairs(int n) { //节约空间写法
if(n==1) return 1;
if(n==2) return 2;
int x=1; //上一楼1种方法
int y=2; //上二楼2种方法
int t=0;
for(int i=3;i<=n;i++){
t=x+y;
x=y;
y=t;
}
return y;
}
};