登台阶爬楼梯问题

登台阶爬楼梯问题

问题描述

有N个台阶,0<N<=50, 每次只跳1个或者3个台阶,输入N, 有多少种方式到达台阶终点

# 示例 1:
输入:n = 3
输出:2
解释:有两种方法可以爬到楼顶。
1.   1 阶 + 1 阶+1阶
2.   3阶

# 示例 2:
输入:n = 4
输出:3
解释:有两种方法可以爬到楼顶。
1.   1 阶 + 1 阶 + 1阶 +  1阶
2.   3阶 + 1阶
3.   1阶 + 3阶

很多时候我们自己对问题的描述所呈现的大都基于固有的思想,我们需要在固有的思想上怎么去优化这个问题才是重点。

-- 首先我们需要寻找规律 
台阶1   【1】   
台阶2   【11】
台阶3   【111,3】 
台阶4   【13 ,31 ,1111】       
台阶5   【113 ,311 ,131,111】        
台阶6   【1113,1131,1311,3111,111111,33】
台阶7   【11113 ,11131,11311,13111,31111,331,133,313,1111111】 

f(1) = 1 
f(2) = 1
f(3) = 2
f(4) = f(1) + f(3) = 3
f(5) = f(2) + f(4) = 4
f(6) = f(3) + f(5) = 6
f(7) = f(4) + f(6) = 9 
...
F(N) = F(N-3) + F(N-1)
其实很好理解:等台阶 只有两种:1 和 3  需要统计的是这两种的个数 也就是我们需要爬的总数。
第 n 级台阶的方案数是爬到第 n−1 级台阶的方案数和爬到第 n−3 级台阶的方案数的和.
递归
#普通递归  重复计算之前的树节点 时间复杂度 O(2^n)  空间复杂度(On)
#优化方法 在此基础上保存之前计算过的节点 使得时间复杂度(On)
def f1(n):
    if n==1:return 1
    elif n==2:return 1
    elif n==3:return 2
    else:
        res=f1(n-1)+f1(n-3)
        return res
        
[f1(i) for i in range(1,10)]
#[1, 1, 2, 3, 4, 6, 9, 13, 19]
#优化 存储之间计算的节点数据 如计算f(5)时  不必再次计算f(4)和f(2) 存储

 def f11(n):
        memo=[]
        if n == 0 or n == 1:
            return 1
        if memo[n] == -1:
            memo[n] = f11(n- 1, memo) + f11(n - 3, memo)
        return memo[n]
    # memo: [-1] * (n - 1)
    # -1 表示没有计算过,最大索引为 n,因此数组大小需要 n + 1
    return f11(n, [-1] * (n + 1))

动态规划

# 动态规划
def funa(n):
    if n<2:
        return 1
    if n>=2:
        dp = [0]*(n+1)
        dp[0] = 1
        dp[1] = 1
        dp[2] = 2
        for i in range(3,n+1):
            dp[i] = dp[i-1] + dp[i-3]
    return dp[n-1]
#空间复杂度O(n)  时间复杂度O(n)
[funa(i) for i in range(1,10)]
#[1, 1, 2, 3, 4, 6, 9, 13, 19]
滚动数组
#动态规划
def f3(n):
    if n==0:return 0#初始化前3项
    if n==1:return 1
    if n==2:return 1
    if n==3:return 2
    p,q,r=1,1,2
    # 从第4项开始遍历,由于n算在结果中,故range第二个数为n+1,区间为[3, n+1)
    for i in range(4,n+1):#节省空间  不使用数组
        p ,q, r = q , r ,(r+p)#每一项都是 前i-1  和 前 i-3  通过移动状态
    return r
# 时间复杂度:循环执行 nn 次,每次花费常数的时间代价,故渐进时间复杂度为 O(n)。
# 空间复杂度:这里只用了常数个变量作为辅助空间,故渐进空间复杂度为 O(1)。
[f3(i) for i in range(1,10)]
#[1, 1, 2, 3, 4, 6, 9, 13, 19]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,针对您的问题,我来讲一下动态规划爬楼梯问题5个台阶的分析方法。 在动态规划中,我们通常会使用一个数组来存储子问题的解,以便后续的子问题可以直接使用已解决的子问题的解,从而避免重复计算。对于爬楼梯问题,我们可以使用一个一维数组来存储到达每个台阶的不同路径数量。 以下是对于5个台阶的分析方法: 1. 递推法:根据题目可知,到达第n个台阶的方法数为到达第n-1和第n-2个台阶的方法数之和,因此可以使用递推的方式来求解。具体实现可以使用一个一维数组dp来存储到达每个台阶的方法数,从dp[0]开始逐个计算,最终返回dp[n]即可。 2. 递归法:类似于递推法,也是通过递归的方式来求解。递归终止条件为到达第0个台阶和第1个台阶的方法数分别为1和1,递归求解到达n-1和n-2个台阶的方法数,最终返回它们之和即可。 3. 记忆化搜索法:在递归法的基础上,加入了记忆化的思想,即在求解每个子问题时,先查看该子问题是否已经计算过,如果已经计算过,则直接返回已有的解。如果没有计算过,则递归求解,并将结果存储到一个数组中,以便后续的子问题可以直接使用已解决的子问题的解。 4. 斐波那契数列法:利用斐波那契数列的递推公式,即f(n)=f(n-1)+f(n-2),来求解爬楼梯问题。具体实现可以使用两个变量f1和f2来存储f(n-1)和f(n-2)的值,然后依次更新它们的值,最终返回f(n)即可。 5. 矩阵快速幂法:在斐波那契数列法的基础上,利用矩阵快速幂的思想,可以将时间复杂度从O(n)降低到O(logn)。具体实现可以将斐波那契数列的递推公式转化为矩阵的形式,然后使用矩阵快速幂的方式来求解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elvis_hui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值