70. Climbing Stairs
问题表述:
You are climbing a staircase. It takes n steps to reach the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
思路:这是道Fibonacci问题,当n>=2时,F(N) = F(N-1)+F(N-2),有些区别是,斐波那契序列是从0开始,即:
n | f(n) |
---|---|
0 | 0 |
1 | 1 |
2 | 1 |
3 | 2 |
4 | 3 |
5 | 5 |
6 | 8 |
而爬楼梯对应:
n | f(n) |
---|---|
0 | 1 |
1 | 1 |
2 | 2 |
3 | 3 |
4 | 5 |
5 | 8 |
6 | 13 |
Example 1:
Input: n = 2 Output: 2 Explanation: There are two ways to climb to the top.
- 1 step + 1 step
- 2 steps
Example 2:
Input: n = 3 Output: 3 Explanation: There are three ways to climb to the top.
- 1 step + 1 step + 1 step
- 1 step + 2 steps
- 2 steps + 1 step
解法1:
递归,但这种在leetcode提交会超时。
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);
}
解法2:
利用数组进行递归:
int climbStairs(int n) {
if(n<=1) return 1;
std::vector<int> dp(n);
dp[0] = 1;
dp[1] = 2;
for(int i=2;i<n;i++)
{
dp[i] = dp[i-1] + dp[i-2];
}
int re = dp[n-1];
return re;
}
解法3:
因为每次的结果都是前两次结果之和,可以使用两个变量记住这两个结果,亲测这种方案也会超时。
int climbStairs(int n){
int first = 1;
int second = 1;
while(n--){
int sum = first + second;
first = sum - first;
second = sum;
}
return first;
}
解法4:
推荐:
直接试用Fibonacci的推导公式,推导过程推荐看:
https://zhuanlan.zhihu.com/p/26679684
注意这里是n+1,原因可以看开头的表格
int climbStairs2(int n) {
if(n<=1) return 1;
double sqrt_5 = sqrt(5.0);
return (1/sqrt_5)*(pow((1+sqrt_5)/2,n+1)-pow((1-sqrt_5)/2,n+1));
}