分治

基本思想:

分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解,是一种分目标完成程序算法,简单的问题可用二分法完成。

分治算法的解题步骤一般如下:

        (1)分解,将要解决的问题划分成若干规模较小的同类问题;

        (2)求解,当子问题划分得足够小时,用较简单的方法解决

        (3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解


例题1

 一个列表中存在n个数据的时候,找到其中的最大值。

思路:将n个数据分为2部分,分开的部分继续分为两部分,直到剩下的部分里只剩下两个值,进行比较,之后返回上一级进行比较,继续返回,直到得到答案。

def get_min(number):#寻最小值函数
    if len(number) == 1:
        return number[0]
    else:
        if number[1]>number[0]:
            return number[0]
        else:
            return number[1]
# 分治法
def solve(number):
    n = len(number)
    if n <= 2:  # 数据规模小于等于2使用get_min()函数
        return get_min(number)
    # 分解(子问题规模为 n/2)
    left_list, right_list = number[:n // 2], number[n // 2:]#切片,//表示整除
    # 递归(树),分治
    left_min, right_min = solve(left_list), solve(right_list)
    # 合并
    return get_min([left_min, right_min])
#if __name__ == "__main__":

# 测试数据
test_list = [33,52,2,25,63,75,43,72,45,97,53,25,14,18,3,5]
# 求出最小值
print(solve(test_list))

例题2

找到一组数据中第 k 小的元素

思路:找一个中间值,数据分成比中间值大和比中间值小的两部分,之后根据小的部分的数据长度,看要选的第n个的n是不是和数据长度相等,相等就返回数好了,不相等看是在较小部分进行分割数据还是在较大部分进行分割数据,后面循环,直到结果出来。

#找一个中间值,数据分成比中间值大和比中间值小的两部分
def divide(number): #划分函数
    fis = number[0] #定义一个主元
    litter = [x for x in number[1:] if x < fis]#比主元小的元素存放一个列表,列表推导式
    big = [x for x in number[1:] if x >= fis]#比主元大的元素存放一个列表,也是列表推导式
    return fis,litter,big
#之后根据小的部分的数据长度,看要选的第n个的n是不是和数据长度相等,相等就返回数好了,不相等看是在较小部分进行分割数据还是在较大部分进行分割数据,后面循环,直到结果出来。
def find(number,key):# 查找第 k 小的元素
    fis,litter,big = divide(number) #分解
    n = len(litter)
    if n == key:
        return fis#找到
    elif n < key:
        return find(big,key-n-1)#递归分治
    else:
        return find(litter,key)#递归分治
#if __name__ == '__main__':
list = [3, 45, 18, 65, 53,15,26,37, 27, 49, 17, 93, 0, 100, 13, 62, 52, 7, 24, 29]
print('第5小的元素:',find(list,5))
print('第10小的元素:',find(list,10))

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值