算法-递归

一、什么是递归?

  递归是一种分而治之的一种解题思路

二、使用递归的场景

  一般使用递归要下面这几个条件

  1)将一个复杂的问题拆分成规模比较小的若干部分

  2)每个子问题的求解思路是一模一样的

  3)有递归的结束条件

 

实例1:找密码串

import string
import random

people = {}.fromkeys(string.ascii_uppercase, False)
people[random.choice(string.ascii_uppercase)] = ''.join(random.sample(string.ascii_letters+string.digits, 6))


# step1:拆分子问题,这里是查看单个人的的vale
def find_password(people, specific_person):
    return people.get(specific_person, False)


# step2:组合子问题,这里需要查看所有人的value
# 方法1
def find_password2(people, queue=None):
    if not queue:
        queue = list(people.keys())
        return find_password2(people, queue)
    elif queue:
        current_person = queue[0]  # 每次取出队列的第一个人来查找
        if people.get(current_person, False):  # 判断这个人是否有密码(递归结束条件)
            return "找到密码了,密码串是{},在{}的手上".format(people[current_person], current_person)
        else:
            return find_password2(people, queue[1:])
    else:
        return "没找到密码"


print(find_password2(people))


# 方法2
def find_password3(people):
    def check_password(p):
        if p:
            k, v = p.popitem()
            if v:
                return k, v
            return check_password(p)
        else:
            return "没找到密码"
    return check_password(people)


print(find_password3(people))

 

实例2:

  设计函数:给定一个数字N, 打印正序1到N

  设计函数:给定一个数字N, 打印倒序N到1

# 拆分子问题
def print_number(N):
    print(N)


# 组合子问题(顺序打印)
def print_sort_number(N):
    if N<1:  # 递归结束条件
        return
    print_sort_number(N-1)  # 递归调用
    print(N)  # 注意处理语句的摆放位置


print_sort_number(10)

结果:
1
2
3
4
5
6
7
8
9
10


# 组合子问题(逆序打印)
def print_reverse_number(N):
    if N<1:  # 递归结束条件
        return
    print(N)  # 注意执行语句的摆放位子
    print_reverse_number(N-1)  # 递归调用

print_reverse_number(10)

结果:
10
9
8
7
6
5
4
3
2
1

# 备注:递归语句和处理语句的位置顺序是影响结果重要的因素

 

实例3:

  十进制正整数转换为2进制

# 拆分子问题
def int2bin(n):
    remainder = n % 2
    divisor = n / 2
    return str(remainder)

# 组合子问题
def int2bin2(n):
    remainder = n % 2
    divisor = n / 2
    if n < 1:  # 递归结束条件
        return "0b"
    return int2bin(n) + str(remainder)  # 递归调用

 

实例4:

  报数游戏:
  第一个人报数 1
  第二个人报数 11
  第三个人报数 21
  第四个人报数 1211
  第五个人报数 111221
  第六个人报数 312211

  . . . . . . .

# 拆分子问题
def report_number(n):
    last_string = report_number(n-1)  # 获取上一个报数的字符串
    first_num = last_string[0]
    amount = 1
    result = ""
    for i in last_string[1:]:
        if i == first_num:
            amount += 1
        else:
            result += str(amount)+first_num
            first_num = i
            amount = 1
    result += str(amount)+first_num
    return result  # 返回字符串


# 组合子问题
def report_number(n):
    if n == 1:  # 递归结束条件
        return '1'
    last_string = report_number(n-1)  # 获取上一个报数的字符串(递归调用)
    first_num = last_string[0]
    amount = 1
    result = ""
    for i in last_string[1:]:
        if i == first_num:
            amount += 1
        else:
            result += str(amount)+first_num
            first_num = i
            amount = 1
    result += str(amount)+first_num
    return result  # 返回字符串


print(report_number(5))

 

总结:

  递归函数一般包括:处理子问题的逻辑(相同部分),递归结束条件,递归调用(3因素)

  在使用递归这个方法的时候,我们不需要去关注每个一次递归返回的结果,只需要关注子问题的处理逻辑,然后把上面这个3个因素拼接起来,这样处理递归问题会更加的简单

 

posted @ 2020-03-31 19:29  海澜时见鲸  阅读(186)  评论(0)    收藏  举报