分治算法详解
来源:互联网 发布:搜狐域名邮箱注册 编辑:程序博客网 时间:2024/06/05 15:04
一、分治算法的基本思想
当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。
所以分治算法中的“分”具体是值用递归解决规模较小的问题 ,”治“具体是指从子问题的解构建原问题的解。具体来讲就是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题可用二分法完成。
二、分治算法解决的问题的特征
分治法所能解决的问题一般具有以下几个特征:
(1)该问题的规模缩小到一定的程度就可以容易地解决;
(2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;
(3)利用该问题分解出的子问题的解可以合并为该问题的解;
(4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
说明:第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归思想的应用;第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法。第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
三、分治算法的基本步骤
分治法解题的一般步骤:
(1)分解,将要解决的问题划分成若干规模较小的同类问题;
(2)求解,当子问题划分得足够小时,用较简单的方法解决;
(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。
四、leetcode上关于分治算法的实例
4.1 Pow(x, n)
(1)题意
求解x的n次方,要求时间复杂度为O(logn)。
(2)python代码
class Solution: def myPow(self, x, n): if not n: return 1 if n < 0: return 1 / self.myPow(x, -n) if n % 2: return x * self.myPow(x, n-1) return self.myPow(x*x, n/2)
4.2 Sqrt(x)
(1)题目
求x的开平方根,要求时间复杂度为o(logn)。
(2)python代码
class Solution(object): def mySqrt(self, x): """ :type x: int :rtype: int """ l,r = 0,x while l<=r: mid=(r+l)//2 if mid*mid<= x <(mid+1)*(mid+1): return mid elif x < mid*mid: r=mid else: l=mid+1
五、使用分治算法求解的一些经典问题
(1)二分查找;
(2)大整数乘法;
(3)Strassen矩阵乘法;
(4)棋盘覆盖;
(5)合并排序;
(6)快速排序;
(7)线性时间选择;
(8)最接近点对问题;
(9)循环赛日程表;
(10)汉诺塔。
- 【算法详解】分治算法详解
- 分治算法详解
- 详解分治算法
- 分治算法详解
- 分治算法详解
- 分治算法: 归并排序(详解)
- 归并排序与分治算法详解
- 分治算法
- 分治算法
- 分治算法?
- 【算法】分治
- 【算法】分治
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- View那些事儿(2) -- 理解MeasureSpec
- 计算机网络--ARP地址解析协议详解
- HDU6153 A Secret 扩展KMP
- Java标识符
- 2017ccpc网络赛——Friend-Graph
- 分治算法详解
- JavaScript-打开新窗口(window.open)
- vm中的新生代Eden和survivor区
- hibernate Mysql 自增长 注解配置,表无关联的注解方式关联查询
- 单例模式
- 虚函数在子类和父类中的内存布局
- 优先级问题
- Zookeeper学习笔记(三)Master选举
- 【hdu1029 】Ignatius and the Princess IV