[LeetCode] 70. Climbing Stairs(爬楼梯)
-
Difficulty: Easy
-
Related Topics: Dynamic Programming
Description
You are climbing a stair case. It takes n steps reach to top.
你在爬一座楼梯,到达楼梯顶端需要爬 n 阶
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
每一次你都可以选择爬 1 阶或 2 阶。问爬到楼梯顶端有多少种走法?
Examples
Example 1
Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps
Example 2
Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step
Constraints:
1 <= n <= 45
Hints
-
To reach nth step, what could have been your previous step? (Think about the step sizes)
为了到达第 n 阶楼梯,在这之前你走了多少步?(考虑楼梯的数量)
Solution
要攀上第 \(n\) 级台阶,有两种做法:
-
在第 \(n - 1\) 级台阶上跨 1 个台阶;
-
在第 \(n - 2\) 级台阶上跨 2 个台阶。
于是求第 \(n\) 级台阶有多少种不同的走法,只要考虑第 \(n - 1\) 级台阶和第 \(n - 2\) 级台阶有多少种走法,二者相加即为所求。
细心的朋友可能会发现,用上述方法产生的是一个斐波那契数列(这里规定第 0 级台阶也有 1 种走法,即站在原定)。于是问题转化为求斐波那契数列的第 \(n + 1\) 项,这里可以用迭代法,也可以直接套用通项公式
\[F_n = \frac{1}{\sqrt{5}}[(\frac{1+\sqrt{5}}{2})^n-(\frac{1-\sqrt{5}}{2})^n]
\]
至于这个通项公式的推导,网上有大量资源,这里不再赘述。
本人采用迭代方法,代码如下:
class Solution {
fun climbStairs(n: Int): Int {
if (n == 1) {
return 1
}
if (n == 2) {
return 2
}
val dp = IntArray(n + 1)
dp[0] = 1
dp[1] = 1
dp[2] = 2
for (i in 3..dp.lastIndex) {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp.last()
}
}