Loading

[LeetCode] 70. Climbing Stairs(爬楼梯)

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

  1. To reach nth step, what could have been your previous step? (Think about the step sizes)

    为了到达第 n 阶楼梯,在这之前你走了多少步?(考虑楼梯的数量)

Solution

要攀上第 \(n\) 级台阶,有两种做法:

  1. 在第 \(n - 1\) 级台阶上跨 1 个台阶;

  2. 在第 \(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()
    }
}
posted @ 2020-10-15 09:14  Zhongju.copy()  阅读(266)  评论(0编辑  收藏  举报