问题描述:
老板有一袋金块(共n块),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块。假设有一台比较重量的仪器,我们希望用最少的比较次数找出最重的金块。
要求:
- 1)设计一算法求解该问题? (分治法解)
- 2)计算其时间复杂度?(要求写出递推公式,及其求解过程)
代码如下:
# -*- coding: utf-8 -*-
"""
Created on Wed Oct 12 11:58:16 2022
@author: Dell
"""
def min(x, y): #判断两块的大小
if x > y:
return y
else:
return x
def max(x, y):
if x < y:
return y
else:
return x
def search_min(list, left, right): #left为左边的索引,right为右边的索引
if left == right or right - left == 1:
return min(list[left],list[right])
else:
mid = (left + right) // 2
list[left] = search_min(list, left, mid)
list[right] = search_min(list, mid, right)
return min(list[left],list[right])
def search_max(list, left, right):
if left == right or right - left == 1:
return max(list[left],list[right])
else:
mid = (left + right) // 2
list[left] = search_max(list, left, mid)
list[right] = search_max(list, mid+1, right)
return max(list[left],list[right])
if __name__=='__main__':
list = [2,5,98,20,50,14]
list1 = list.copy()
left = 0
right = len(list) - 1
print('金块重量为:',list)
print('最轻的金块为:',search_min(list,left,right))
print('最重的金块为:',search_max(list1,left,right))
- 第一步,将所有元素序列一分为二,得到两个长度基本相同的子序列;
- 第二步,若子序列较长则继续细分重复以上一分为二的步骤,直至子序列的长度不大于1,找到每个子序列的最大值与最小值;
- 第三步,将子序列合并成一个新数列,最大值取两个子序列最大值中较大的一个,最小值取两个子序列最小值中较小的一个,直至所有子序列全部合并,实现函数即为FinfMaxMin函数;
递推公式:
T(n) = 2T(n/2) + 2
= 2(2T(n/4)) + 2 + 2 = 4T(n/4) + 22
= 8T(n/8) + 23
…
= 2xT(n/2x) + 2x
这里如果令n = 2x ,则x=logn,
T(n) = nT(1) + n
= nO(1) + n
= O(n)