n阶楼梯,一次走1,2,3步,求多少种不同走法

本文探讨了爬楼梯问题的不同算法实现,包括递归遍历所有路径、仅计算路径数量的正向迭代与反向递推方法,并对比了各种方法的时间与空间效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

##已知n阶楼梯,一次可以迈1,2,3步。求所有走法
## 如果要列出走法,时间复杂度太高,O(n)=2**n,前两个函数遍历走法。
## 如果只是单纯列出走法数量,就简单多了,也但是很容易内存爆表。

## n层走法,可以视为n-1层再走一步,n-2层走两步,n-3层走三步。题目都可以按这个思路解决
import copy,time
lv=5
n1=1000000
fzd=0
lg=[]
if lv<=1:
    def dg(ln,n,l):
        global fzd
        fzd+=1
        if ln<n:
            l1=l[:]+[1]
            l2=l[:]+[2]
            l3=l[:]+[3]
            return dg(ln+1,n,l1),dg(ln+2,n,l2),dg(ln+3,n,l3)
        if ln==n:
            return lg.append(l)
    
    ##for j in range(10):
    ##    dg(0,j,[])
    ##    print(len(lg))
    ##    lg=[]
    t=time.time()
    dg(0,n1,[])
    print('dg1 %s阶用时%s s,时间复杂度%s'%(str(n1),str(time.time()-t),fzd))
    lg=[]
    fzd=0
## 另一种递归 可以将n阶台阶分解为走一步+n-1阶,走两步+n-2阶,走三步+n-3阶
## 时间复杂度太高了。
if lv<=2:
    def dg2(n):
        global fzd
        for i in range(1,n+1):
            if i==1:
                lg.append([[1]])
            elif i==2:
                lg.append([[1,1],[2]])
            elif i==3:
                lg.append([[1, 1, 1],[1, 2],[2, 1],[3]])
            else:
                ##深拷贝耗时太长
                ##ln1,ln2,ln3=copy.deepcopy(lg[-1]),copy.deepcopy(lg[-2]),copy.deepcopy(lg[-3])
                ln1,ln2,ln3=lg[-1],lg[-2],lg[-3]
                for j in ln3:
                    fzd+=1
                    j.append(3)
                for j in ln2:
                    fzd+=1
                    j.append(2)
                for j in ln1:
                    fzd+=1
                    j.append(1)     
                lg.append(ln3+ln2+ln1)
        return lg
    t=time.time()
    dg2(n1)
    print('dg2 %s阶用时%s s,时间复杂度%s'%(str(n1),str(time.time()-t),fzd))
    lg=[]
    fzd=0
    ##print(len(lg[-1]))
    ##for n,i in enumerate(lg):
    ##    print('第%s次展示:'%(n+1))
    ##    for j in i:
    ##        print(j)

#### 只计数
## 正面横推
if lv<=3:
    def dgcount(n):
        for i in range(1,n+1):
            if i==1:
                lg.append(1)
            elif i==2:
                lg.append(2)
            elif i==3:
                lg.append(4)
            else:
                lg.append(lg[-3]+lg[-2]+lg[-1])
        return lg

    t=time.time()
    dgcount(n1)
    print('dgcount %s阶用时%s s'%(str(n1),str(time.time()-t)))

## 反向递推
if lv<=4:
    def dgcount2(n):
        if n==1:
            return 1
        elif n==2:
            return 2
        elif n==3:
            return 4
        else:
            return dgcount2(n-1)+dgcount2(n-2)+dgcount2(n-3)

    t=time.time()
    dgcount2(n1)
    print('dgcount2 %s阶用时%s s'%(str(n1),str(time.time()-t)))
## 正面横推2
if lv<=5:
    def dgcount3(n):
        if n>3:
            num1=4
            num2=2
            num3=1
        elif n==1:
            return 1
        elif n==2:
            return 2
        elif n==3:
            return 4
        for i in range(4,n+1):
            num1,num2,num3=num1+num2+num3,num1,num2
        return num1

    t=time.time()
    dgcount3(n1)
    print('dgcount3 %s阶用时%s s'%(str(n1),str(time.time()-t)))

转载于:https://www.cnblogs.com/offline-ant/p/9382523.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值