【Python】使用算法【递归法】【动态规划】【矩阵快速幂】解决爬楼梯问题:假设你正在爬楼梯。需要n阶你才能到达楼顶。每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?

题目分析:

(1)若爬1阶台阶,则仅有1种走法。

(2)若爬2阶台阶,则有1+1和一步跨两阶台阶共2种走法。

(3)若爬3阶台阶,则有1+1+1、1+2和2+1共3种走法。

(4)若爬4阶台阶,则有1+1+1+1,1+1+2根据顺序有3种不同的走法和2+2共5种走法。

   ......以此类推,我们可以列出如下式子:

f(x)=f(x-1)+f(x-2)

可以看出这是一个斐波那契数列。

【方法一】递归方法:

def climbStairs(n):
    if n<2:
        return 1
    else:
        return (climbStairs(n-1)+climbStairs(n-2))
n=int(input("请输入台阶数:"))
print(climbStairs(n))

时间复杂度:O(2^{n})

空间复杂度:O(n)

【方法二】记忆化递归:

以上算法使用递归将进行大量重复计算,记忆化递归可以将已算出的f(x)进行保存,可直接拿来使用。代码如下:

def climbStairs(n):
    memory=[0 for i in range(n+1)]        # 初始化一个数组,赋初值为0
    return climbStairsMemory(n,memory)
def climbStairsMemory(n,memory):
    if memory[n]>0:                       # 如果大于0,说明当前数值已经计算出并存储在数组中
        return memory[n]                  # 直接从数组中拿出来使用,不用重复计算
    if n==1:
        memory[n]=1
    elif n==2:
        memory[n]=2
    else:
        memory[n]=climbStairsMemory(n-1,memory)+climbStairsMemory(n-2,memory)
    return memory[n]
n=int(input())
print(climbStairs(n))

时间复杂度:f(x)=O(n)

空间复杂度:f(x)=O(n)

【方法三】动态规划法

我们可以运用到滚动数组法的思想,滚动数组是一种算法优化思想,它通过让数组滚动起来,每次都使用固定的几个存储空间,以达到压缩和节省存储空间的目的。这种思想主要应用在动态规划和状态压缩算法中,例如在递推或动态规划问题如01背包问题中,滚动数组可以帮助降低空间复杂度。在某些情况下,某些二维动态规划方程可以直接降阶为一维,甚至有时可以降低时间复杂度。简而言之,滚动数组是一种通过观察动态规划方程来巧妙地降低计算复杂度的思想。

代码如下:

def climbStairs(n):
    a,b = 1,1
    for i in range(n):
        a,b =b,a+b
    return a
n=int(input("请输入台阶数:"))
print(climbStairs(n))

时间复杂度:O(n)

空间复杂度:O(1)

【方法四】矩阵快速幂

矩阵快速幂是一种高效的算法,用于计算矩阵的幂次方,其基本原理是将矩阵的乘法操作转换为幂次运算,从而减少重复计算次数。我们可以构建一个递推关系:

                           \begin{bmatrix} a &b\\ c&d \end{bmatrix}\begin{bmatrix} f(n)\\f(n-1) \end{bmatrix}=\begin{bmatrix} f(n)+f(n-1)\\f(n) \end{bmatrix}=\begin{bmatrix} f(n+1)\\f(n) \end{bmatrix}

代入几个数字得出:

                                    \begin{bmatrix} a &b \\ c& d \end{bmatrix}=\begin{bmatrix} 1 &1 \\ 1& 0 \end{bmatrix}

由此可得:

                                    \begin{bmatrix} f(n+1)\\f(n) \end{bmatrix}=\begin{bmatrix} 1 &1 \\ 1& 0 \end{bmatrix}^{n}\begin{bmatrix} f(1)\\f(0) \end{bmatrix}

因此我们只要快速计算矩阵\begin{bmatrix} 1 &1 \\ 1& 0 \end{bmatrix}的n次幂,就可以得出f(n)的值。代码如下:

def climbStairs(n):
    q=[[1,1],[1,0]]
    res=pow(q,n)
    return res[0][0]    # 结果值的第一位就是所求结果
# 快速幂代码
def pow(a,n):
    ret=[[1,0],[0,1]] # 将ret初始化为单位矩阵,相当于初始化为1
    while n>0:
        if (n&1)==1:   # 位与操作可以取余数用于判断n的二进制最后一位数是否为1
            ret=multiply(ret,a)  # 若为1,则与ret进行相乘
        n>>=1          # 每次循环都进行右移操作
        a=multiply(a,a)   # 否则将进行幂运算
    return ret
# 矩阵相乘代码
def multiply(a,b):
    c=[[0,0],
       [0,0]]
    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
n=int(input("请输入台阶数:"))
print(climbStairs(n))

时间复杂度:O(logn)

空间复杂度:O(1)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值