Leetcode70. 爬楼梯(公式+动态规划优化)
作者:互联网
题目链接:https://leetcode-cn.com/problems/climbing-stairs/
解题思路
方法一:数学公式
这是一道很经典的斐波拉契数列题,所以可以用数学公式计算出来。
F
n
=
1
/
5
[
(
1
+
5
2
)
n
−
(
1
−
5
2
)
n
]
F_{n}= 1/\sqrt{5}\left[\left(\frac{1 + \sqrt{5}}{2}\right)^n - \left(\frac{1 - \sqrt{5}}{2}\right)^n\right]
Fn=1/5
[(21+5
)n−(21−5
)n]
代码
public class Solution {
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);
}
}
方法二:动态规划
动态规划的关键就是能转化为更小规模的子问题。那我们首先想一下,如果要达到第n
层,只走一次有几种方法能达到?答案显而易见,只有在n-1
和n-2
阶台阶时能一次达到n
阶(因为题目中说一次只能走一步或者两步)。那我们就能的出dp[i] = dp[i - 1] + dp[i - 2];
我们再看一下初始条件,第一阶只有一种方法。
代码
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n + 1];
dp[0] = 1; //为了方便我们假设第0阶有1中方法
dp[1] = 1; //到达第一阶只有一种方法
for(int i = 2; i <= n; i++)
dp[i] = dp[i - 1] + dp[i - 2]; //到达第i层只有可能从i-1层和i-2层才能一次到达
return dp[n];
}
}
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(n)
方法三:动态规划优化
其实我们不难发现第n阶之和前面第n-1阶和n-2阶有关,所以我们可以不必用一个数组存储,而可以直接用3个变量保存这三个状态。
代码
class Solution {
public int climbStairs(int n) {
int a = 1, b = 1, c;
for(int i = 2; i <= n; i++) {
c = b + a;
a = b;
b = c;
}
return b;
}
}
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)
标签:Leetcode70,爬楼梯,int,公式,复杂度,sqrt5,Math,public,dp 来源: https://blog.csdn.net/qq_44713772/article/details/116486238