70 - 爬楼梯 - python

225 阅读2分钟

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 阶 + 12.  2

示例 2:

输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 阶 + 1 阶 + 12.  1 阶 + 23.  2 阶 + 1

首先我们将简单的前几种情形进行列举

n爬法总数
111
21 +1 、22
31 + 1 + 1、1 + 2、2 + 13
41 + 1 + 1 + 1、1 + 1 + 2、2 + 2、1 + 2 + 1、2 + 1 + 15

从表格中可以很明显的看出它满足斐波那契数列的性质 F ( n ) = F ( n − 1 ) + F ( n − 2 ) F(n) = F(n-1) + F(n-2) F(n)=F(n−1)+F(n−2),因此可以使用斐波那契数列的公式进行求解。


在这里插入图片描述

class Solution:
    def climbStairs(self, n: int) -> int:
        if n == 0: return 0
        if n == 1: return 1
        if n == 2: return 2

        p, q = 1, 2
        for i in range(2, n):
            temp = p + q
            p = q
            q = temp
        
        return q

斐波那契数列的做法需要我们有一定的经验,以及列举一些简单的情形来判断是否满足。此外,从斐波那契数列的做法中也可以看出,该问题可以被分解为最优子结构的子问题,即最优解可以从其子问题的最优解有效构建,所以可以采用动态规划的方法求解。

第 i i i阶台阶可以看成是第 i − 1 i-1 i−1阶再爬一阶、第 i − 2 i-2 i−2阶再爬两阶,即第 i i i阶的爬法总数是第 i − 1 i-1 i−1阶和第 i − 2 i-2 i−2阶总数的和,所以可以得到动态转移方程: d p [ i ] = d p [ i − 1 ] + d p [ i − 2 ] dp[i] = dp[i-1]+dp[i-2] dp[i]=dp[i−1]+dp[i−2]

class Solution:
    def climbStairs(self, n: int) -> int:
        if n == 0: return 0
        if n == 1: return 1
        if n == 2: return 2

        dp = [1, 2]

        for i in range(2, n):
            dp.append(dp[i -1 ] + dp[i - 2])

        return dp[-1]