Leetcode——爬楼梯(最详细!)

爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

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

示例 1:

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。

  1. 1 阶 + 1 阶
  2. 2 阶
    示例 2:

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

思路:
爬楼梯算是DP的经典题目,递归+记忆化,也就是递推,我们需要定义好状态,还有状态的转移方程。最后爬的步数还是得看之前的,即依赖之前的步骤。

1.反着考虑,有几种方案到第i阶楼梯,答案是2种:

第i-1阶楼梯经过一步
第i-2阶楼梯经过两步
假设count(i)表示到第i阶楼梯方案的个数,则count(i) = count(i-1) + count(i-2)
第一阶是1种,第二阶是2种。代码如下:

class Solution:
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        count = [1,2]   #一次就只能走这两步
        for i in range(2,n):
            count.append(count[i-1]+count[i-2])	#不停地把后面的台阶的结束放到count里面
        return count[n-1]

但是太慢了。。。这里起码O(n!)

2.我们想到可以转化为fibonaqi问题。假设一共有10阶楼梯,每步可以爬1步或者2步,那么你爬到10阶一共有两种方法,从8阶爬2步,或从9阶爬1步,那么爬到9阶也是这样,那这就是一共基本的斐波那契数列。
dp[i] = dp[i-1] + dp[i-2]
i-1的时候跳一步可以到达i
i-2的时候跳一步是i-1,这个变成dp[i-1]的子问题了,直接跳两步可以到达i

class Solution:
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        dp = [1 for i in range(n+1)]   #状态的定义
        for i in range(2,n+1):
            dp[i] = dp[i-1]+dp[i-2]	#状态转移方程
        return dp[n]

这里应该是O(n)
3.还有一种更快速的,列表初始化好,然后再用fibonaqi数列转移方程。

class Solution:
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        condition = [0]*(n+1)		#牛逼的初始化列表
        condition[0] = 1
        condition[1] = 1
        for i in range(2,n+1):
            condition[i] = condition[i-1]+condition[i-2]   #依然还是状态转移fibonaqo
        return condition[n]

这里列表初始化只用来O(1),最后复杂度为O(n)

你可能感兴趣的:(LeetCode)