题目描述
example
input : n = 2
output : 2
note : 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
input : n = 3
output : 3
note : 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
解题思路
列举几个简单的台阶数,做总结,可以发现爬楼梯的方案数满足斐波那契数列。如:
状态转移方程:dp[i] = dp[i-1] + dp[i-2]
初始,dp[1] = 1, dp[2] = 2
从3到n遍历结束后,返回dp[n]即是爬楼梯的方案数
可以维护dp数组,保留每一个n可以产生的方案数
也可以不维护数组,动过迭代变量保留最后的方案数
思路2 递归(会超出时间限制)
- 从动态规划变形得到的
- 递归出口:
- n = 1,返回1
- n = 2,返回2
- 递归过程:
- 返回 loop(n - 1) + loop(n - 2)
思路3 数学通项公式
- 斐波那契数列的通项公式为:
- f(n)=[((1+√5) / 2)^n^−((1−√5)/2)^n^] / √5
代码(Java)
思路1代码
public class Solution1 {
public int climbStairs(int n) {
if (n == 1){
return 1;
}
int[] dp = new int[n + 1];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
// 不借助dp数组的写法
public int climbStairs2(int n){
int p = 0;
int q = 1;
int r = p + q;
for (int i = 2; i <= n; i++){
p = q;
q = r;
r = p + q;
}
return r;
}
}
思路2代码
public class Solution2 {
public int climbStairs(int n) {
// 超出时间限制O(2^n)
if (n <= 1) {
return 1;
}
return climbStairs(n - 1) + climbStairs(n - 2);
}
}
思路3代码
public class Solution3 {
public int climbStairs(int n) {
double sqrt5 = Math.sqrt(5);
double fibn = Math.pow((1 + sqrt5) / 2, n + 1) - Math.pow((1 - sqrt5) / 2, n + 1);
return (int) Math.round(fibn / sqrt5);
}
}
本文作者:
whtli
本文链接: https://hexo.whtli.cn/archives/a47c4019.html
版权声明: 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
本文链接: https://hexo.whtli.cn/archives/a47c4019.html
版权声明: 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。