分治:分治和动态规划的区别,二分检索递归和迭代方式实现

分治法

分治一般可以直接使用递归实现,在不考虑空间消费的情况下和迭代方式时间消耗相差不多

==================================================================

分治一般形式: T(n) = k*T(n/m) + f(n)

k为子问题个数,一般均分或者等比分

n/m问题规模,一般情况下m已经确认了子问题的个数,可以通过变换减少为a个

f(n) 为数据的处理,划分和综合工作量,可以增加预处理,从而减少在递归里面的操作

也就是把递归里面的操作尽量放在循环体外面处理

==================================================================

问题规模和个数k*T(n/m),k<=m,当然理论上也有T(n-m)的情况,在这种情况下子问题变得很多,且子问题可能相互依赖,不独立,无法逐个解决,需要按照顺序解决子问题,通常那种情况下使用动态规划解决。

所以可以看出来分治和动态规划的区别:一个子问题多,多的还有存在依赖,一个子问题少,且子问题独立,从一般的状态转移方程也可以看出区别,一个是减法衰减,一个是除法衰减。

这里还有一个思考,假如一个问题可以分解成很多个子问题,且子问题独立,这时直接使用分治或者是直接使用动态规划,都是和蛮力算法没有区别,这时就需要考虑使用分治优化策略,减少子问题k,或者通过减少步骤f(n)来优化。

二分检索

二分检索原问题可以看成3个情况,检索目标就在middle,检索目标在middle左边,检索目标在middle右边,f[left,right] = f[middle] or f[left,middle-1] or f[middle+1,right],

实际上二分检索可以看成分支限界法,arr[middle] 和 target比较剪枝,是分支限界的话,那么就需要知道解空间,解空间就是,检索目标的位置,通过深度增加,不断精确检测目标的位置,直到位置精确到1,[模糊位置,缩小范围,缩小范围,…,精确到1],这个过程是满足多米诺性质的,可以用剪枝来减少搜索空间。

#%%
# 注意递归的返回值,递归的要返回的话,要前后一致,或者直接基于某一层考虑,把递归看成结果
def binary_Serach_recursive(arr,left,right,target):
        
    middle = (left + right) // 2
    # 递归出口
    if left > right :
        return(-1)
    
    if arr[middle] == target:
        return(middle)
            
    elif arr[middle] < target:
        # 这里没有return的话,结果就没法return出来
        return binary_Serach_recursive(arr,middle+1,right,target)
        
    else:
        return binary_Serach_recursive(arr,left,middle-1,target)
        
def binary_Serach_iterative(arr,target):
    left = 0
    right = len(arr)-1
    
    # 循环体条件
    while left <= right:
        
        middle = (left + right) // 2
        
        if arr[middle] == target:
            return middle
        elif arr[middle] < target:
            left = middle +1
        else:
            right = middle -1
            
    return -1



#%%
arr = [7,3,66,33,22,66,99,0,1]
sort_arr = sorted(arr)
print(sort_arr)
print(binary_Serach_recursive(sort_arr,0,len(arr)-1,22))
print(binary_Serach_recursive(sort_arr,0,len(arr)-1,100))
print(binary_Serach_iterative(sort_arr,22))
print(binary_Serach_iterative(sort_arr,100))

[0, 1, 3, 7, 22, 33, 66, 66, 99]
4
-1
4
-1

猜你喜欢

转载自blog.csdn.net/weixin_40759186/article/details/84952807