python实现递归问题

一、递归算法

递归出口:递归终止条件

递归体:分而治之,将大问题转换成小问题,逐步求解

二、递归实例

实例一:

有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第3个月又生一对兔子,假如兔子都不死, 从控制台输入第N个月,显示此时兔子总数(对)。

月份兔子数(对)递归算法
111
211
321+1
432+1
553+2
685+3
7138+5
82113+8
93421+13
105524+21

根据表格的规律可知,当月的兔子总数=上个月兔子总数+上上个月的兔子总数,第1、第2个月的兔子数为1对

递归出口:第1个月、第2个月的兔子总数是1对

递归体:当月的兔子总数=上个月兔子总数+上上个月的兔子总数

代码实现:

def rabbit(month):
    if month <=2:
        return 1
    else:
        return rabbit(month-1)+rabbit(month-2)

测试用例:

for i in range(1,11):
    print(rabbit(i),end = " ")

# 测试结果
# 1 1 2 3 5 8 13 21 34 55

实例二:

list = [1, 2, 3, [4, 5, 6, [7, 8, 9]], 10, [11, [12, [13, 14]], 15], 16]
将list转换成[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

分析:将多维列表转换成一维列表

递归出口:当列表中的元素类型不是list类型,则输出到一维列表中

递归体:高维列表转换为低维列表

代码实现:

def func(list_target):
    result = []
    for item in list_target:
        if type(item) == type(list):
            for i in func(item):
                result.append(i)
        else:
            result.append(item)
    return result

测试用例:

list = [1,2,3,[4,5,6,[7,8,9]],10,[11,[12,[13,14]],15],16]
print(func(list))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

实例三:

猴子吃桃子问题,每天吃一半多吃一个,请问10天前共有多少个桃子?

分析:

最后1天,有1个桃子

假设倒数第2天有x个桃子,根据吃桃子的规则可以用表达式,

计算出最后一天的桃子数:(x/2)-1=1

倒推求得倒数第2天的桃子数x = (1+1)*2=4

同理,推导出倒数第3天桃子数为:(4+1)*2=10

同理,推导出倒数第4天桃子数为:(10+1)*2=22

同理,推导出倒数第5天桃子数为:(22+1)*2=46

。。。。。。

逆向推导正向推导
最后1天:1个(4/2)-1=1
倒数第2天:(1+1)*2=4(10/2)-1=4
倒数第3天:(4+1)*2=10(22/2)-1=10
倒数第4天:(10+1)*2=22(46/2)-1=22
倒数第5天:(22+1)*2=46(94/2)-1=46
倒数第6天:(46+1)*2=94(190/2)-1=94
............
天数桃子个数
11
24
310
422
546
694
7190
8382
9766
101534

递归出口:最后1天,有一个桃子,天数n==1时,桃子数count = 1

递归体:每天吃一半多吃一个,count/2-1

代码实现:

def foo(n,count):
    if n == 1:
        return count
    else:
        count = (count+1)*2
        return foo(n-1,count)

测试用例:

if __name__ == '__main__':
    print(foo(10,1))

三、最后总结

1、对于复杂的递归问题,先从简单的子问题入手,找到其中的规律,可以用笔演算

2、确定递归出口

3、分析大问题与小问题之间的关系与联系,用递归的思想设计递归体

4、测试用例测试递归是否正确

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

花花少年

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

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

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

打赏作者

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

抵扣说明:

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

余额充值