多一些Aha Time,发现技术的美妙🍺|

啊原来是这样呀

园龄:8年3个月粉丝:3关注:9

【算法基础】2.五大算法之分治法

参考资料

分治算法及常见例子https://blog.csdn.net/m0_37741420/article/details/107201275

一文搞懂分治算法https://baijiahao.baidu.com/s?id=1685106188743154112&wfr=spider&for=pc

 

直观理解

 大化小,在小范围内作短小精悍的逻辑处理

 

例子先行

 二分法查找

基于迭代的二分法

复制代码
 1 //基于迭代的二分法
 2 static int binarySearch1(int arr[],int len,int target){
 3     //初始化左右边界
 4     int left=0,right=len-1;
 5     int mid;
 6 
 7     //迭代,中止条件为左右边界之间不再包含待查元素
 8     while(left<=right){
 9         //计算中间位置,向下取整
10         mid=(left+right)/2;
11 
12         //target小于arr[mid],即要寻找的元素在左半边,所以需要设定右边界为mid-1,搜索左半边
13         if(target<arr[mid]){
14             right=mid-1;
15             continue;
16         }
17 
18         //target大于arr[mid],即要寻找的元素在右半边,所以需要设定左边界为mid+1,搜索右半边
19         if(target>arr[mid]){
20             left=mid+1;
21             continue;
22         }
23 
24         if(target==arr[mid]){
25             return mid;
26         }        
27     }
28 
29     //找不到
30     return -1;
31 }
View Code
复制代码

基于递归的二分法,套用递归三板斧

复制代码
 1 //基于递归的二分法
 2 //元素全部非负
 3 static int binarySearch1(int arr[],int left,int right,int target){
 4     //中止条件1
 5     if(left>right){
 6         return -1;
 7     }    
 8     //中止条件2
 9     int mid=(left+right)/2;
10     if(arr[mid]==target){
11         return arr[mid];
12     }
13 
14     //本层逻辑,刷新边界
15     int ret=-1;
16     if(target<arr[mid]){
17         right=mid-1;        
18     }
19     else{
20         left=mid+1;
21     }
22     
23     //调用递归
24     ret=binarySearch1(arr,left,right,target);
25     
26     return ret;
27 }
View Code
复制代码

 

总结提炼

 1理论基础

把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题,直到最后子问题可以简单的直接求解,子问题的解的合并即是原问题的解。

2适用场景

(1)问题的规模缩小到一定的程度就可以容易地解决

(2)问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质(什么是最优子结构?)(当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质)

(3)拆分出来的子问题的解,可以合并为该问题的解

(4)拆分出来的各个子问题是相互独立的,即子问题之间不包含公共的子问题(什么是子问题?先理解为在局部上处理时逻辑更纯粹、无外界干扰的环境吧)

3使用步骤

(1)分解,将原问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题

(2)解决,若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题

(3)合并,将各个子问题的解合并为原问题的解(对于迭代而言是直接返回,对于递归而言是逐层返回并被接受)

4基于递归的伪代码

复制代码
 1 返回值 divideAndConquer(初始递归变量){
 2     //中止条件
 3     if(不持续递归条件){
 4         返回
 5     }
 6 
 7     //本层逻辑
 8     本次拆分后的业务逻辑
 9 
10     //根据策略,分治地调用递归,节省工作量
11     if(某种分治策略){
12         divideAndConquer(一侧递归初始变量);
13     }
14     else{
15         divideAndConquer(另一侧递归初始变量);
16     }
17 }
复制代码

5基于迭代的伪代码

复制代码
 1 while(满足拆分的条件){
 2     //更新状态参数
 3     本次拆分后的业务逻辑
 4 
 5     //将状态参数带入分治策略,节省工作量
 6     if(某种分治策略){
 7         按分治策略的A面,改变并保存拆分条件所涉及的变量
 8     }
 9     else{
10         按分治策略的B面,改变并保存拆分条件所涉及的变量
11     }
12  }
复制代码

 

拓展方向

 1>二分搜索
2>大整数乘法
3>Strassen矩阵乘法
4>棋盘覆盖
5>合并排序
6>快速排序
7>线性时间选择
8>最接近点对问题
9>循环赛日程表
10>汉诺塔

本文作者:啊原来是这样呀

本文链接:https://www.cnblogs.com/OhOfCourse/p/16891935.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   啊原来是这样呀  阅读(10)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起