leetcode 爬楼梯 多种方法解答python实现 代码注释

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

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

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

示例 1:

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

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

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

  1. 1 阶 + 1 阶 + 1 阶
  2. 1 阶 + 2 阶
  3. 2 阶 + 1 阶
class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        # 找出转移方程 f(x) = f(x-1) + f(x-2)
        # f(1) = 1
        # f(2) = 2
        # f(3) = 3
        # f(4) = 5
        # 以此类推
        # 1、递归 一般超时 方法解析 5->(3,4)(3->(1,2)) 4->(2,3) 3->(1,2)
        # 计算了两次的3->(1,2)
        # if n == 1:
        #     return 1
        # if n == 2:
        #     return 2
        # return self.climbStairs(n-1)+self.climbStairs(n-2)

        # 2、为了解决重复计算了3(1,2)的问题 使用列表进行记录判断
        # memo = [0 for _ in range(n+1)]
        # # 结果分析 
        # [0, 0, 2, 0] func(n-1)执行 n==2 return 2
        # [0, 1, 2, 0] func(n-2)执行 n==1 return 1
        # [0, 1, 2, 3] func(n)执行 n==3 return 2+1=3 
        # def func(n): # 递归方法
        #     # 退出条件
        #     if memo[n] > 0: # 有记录的
        #         return memo[n]
        #     if n == 1:
        #         memo[n] = 1
        #     elif n == 2:
        #         memo[n] = 2
        #     else:
        #         memo[n] = func(n-1)+func(n-2)
        #     return memo[n]
        # # 调用函数
        # return func(n)

        # 3、动态规划 记录了计算过的全部状态 但是只有dp[i-1] +dp[i-2]会被用到计算
        # dp = [0 for _ in range(n+1)]
        # dp[0] = 1
        # dp[1] = 1
        # # 迭代
        # for i in range(2,n+1):
        #     dp[i] = dp[i-1] +dp[i-2]
        # return dp[-1]

        # 4、O(1)的空间复杂度设计 只需要存储dp[i-1] +dp[i-2] 滚动变换值
        # 初始化的值决定了你的开始位置 对应的循环次数也要改变
        # 值使用三个变量 为常数级别 空间复杂度为O(1)
        # 与斐波那契数列一致 可以求某一项的值
        # if n == 1: # 特殊条件可以去掉
        #     return 1
        # q , p , r = 1 , 1 , 2  # q , p , r = 0 , 0 ,1
        # for i in range(2 , n): # 2-->0
        #     q = p
        #     p = r
        #     r = q + p
        # return r



        # 5、矩阵快速幂
        # 通过矩阵寻找递推关系 M = [[1,1][1,0]]
        # [[f(n),[f(n-1)]]T * M = [[f(n)+f(n-1)],[f(n)]] = [[f(n+1)],[f(n)]]
        # ...
        # [[f(1)],[f(0)]] = [1,1]
        # 因此不需要每次都去计算递推公式dp[i] = dp[i-1] +dp[i-2]
        # 而是通过计算n次的M矩阵相乘即可
        # (a * b) % p = (a % p * b % p) % p 求A的B次幂的最后三位
        # /**
        #  * 普通的求幂函数
        #  * @param base 底数
        #  * @param power  指数
        #  * @return  求幂结果的最后3位数表示的整数
        #  */
        # long long normalPower(long long base,long long power){
        #     long long result=1;
        #     for(int i=1;i<=power;i++){
        #         result=result*base;
        #         result=result%1000;
        #     }
        #     return result%1000;

        # 快速幂计算 大大减少计算的次数
        # 时间复杂度 O(logn) 空间复杂度 O(1) 用到了常数量的内存空间
        # def pow1(a,n):
        #     res = [[1,0],[0,1]] # 初始化为单位矩阵
        #     while n > 0: # 循环logn次
        #         # n为奇数 提取1出来 1次方 是当前底数即矩阵M的一次方 放到结果中(相乘)
        #         if (n & 1) == 1: # n % 2 == 1
        #             res = matmul(res,a) # 矩阵乘法 行列元素对应相乘再相加
        #         n = n >> 1 # 指数减半 n = n // 2
        #         a = matmul(a,a) # 矩阵平方
        #     return res
        # def matmul(a,b): # 常数量级
        #     c = [[0,0] for _ in range(2) ]
        #     for i in range(2):
        #         for j in range(2):
        #             c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j]
        #     return c

        # 函数调用
        # M = [[1,1],[1,0]] # 矩阵M
        # res = pow1(M,n)
        # return res[0][0]


        # 6、通项公式计算
        # 齐次递推关系公式通过特征根法计算得到通解 要了解求非齐次递归公式的通解
        # 直接将n输入 得到对用的答案 
        # sqrt5 = pow(5,0.5)
        # res = pow((1 + sqrt5) / 2, n + 1)-pow(( 1 - sqrt5) / 2, n + 1)
        # return int(res / sqrt5)

        
        




        





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值