二分法在一个单调有序的集合或函数中查找一个解,每次分为左右两部分,判断解在哪个部分中并调整上下界,直到找到目标元素,每次二分后都将舍弃一半的查找空间,因此效率很高。
若求解的问题的定义域为整数域,对于长度为N的求解区间,算法需要logn次来确定出分界点。
对于定义域在实数域上的问题,可以类似于上面的方法,判断R-L的精度是否达到要求,即R-L>=eps。
如果我们指定二分的次数t,那么对于初始的求解区间长度L,算法结束后的r-l值会为L/2^t。 二分算法的复杂度O(二分次数*单次判定复杂度)。
二分法常见模型
- 1.二分答案 最小值最大(或是最大值最小)问题,这类双最值问题常常使用二分法求解,也就是确定答案后,配合贪心、DP等其它算法来检验这个答案是否合法,将最优化问题转变为判定性问题。例如:将长度为n的序列ai分成最多m个连续段,求所有分法中每段和的最大值最小是多少。
- 2.二分查找 具有单调性的布尔表达式求解分界点,比如在有序数列中求数字 的排名。
三分法适用于求解凸性函数的极值问题,二次函数就是一个典型的单峰函数。
三分法与二分法一样,它会不断缩小答案所在的求解区间。二分法缩短区间利用的原理是函数的单调性,而三分法利用的则是函数的单峰性。
设当前求解的区间为[l,r],令m1=l+(r-l)/3,m2=r-(r-l)/3,接着我们计算这两个点的函数值f(m1),f(m2),之后我们将两点中函数值更优的那个点称为好点(若计算最大值,则更大的那个点就为好点,计算最小值同理),而函数值较差的那个点称为坏点。
我们可以证明,最优点与好点会在坏点同侧。例如,f(m1)>f(m2),则是m1好点而m2是坏点,因此最后的最优点会与m1一起在m2的左侧,即我们的求解区间由变为了[l,m2]。因此根据这个结论我们可以不停缩短求解区间,直至可以得出近似解。
注意,我们在介绍单峰函数时特别强调了“严格”单调性。
若在三分过程中遇到 f(m1) = f(m2),当函数严格单调时,令 l = m1或 r = m2均可。如果函数不严格单调,即在函数中存在一段值相等的部分,那么我们无法判断定义域的左右边界如何缩小,三分法就不再适用。