算法精讲之【二分】

前言:

学习二分有两个境界,第一个境界是见有序用二分,第二个境界是见二段性用二分。

有很多人认为二分只能用于有序的情况下,其实不然,能用二分的前提是具有二段性的特性

下面主要讲解什么是二段性。

二段性就是可以将数组的数据分为两个部分,这样我们就有mid比较的方式,

注意我们将mid的值跟谁比较才能确定在哪个区间也是很重要的点,也就是寻找与mid比较的基准值!

最终二分出来的结果就是在这两个区间的极值。

二分算法的模板:

while(left < right)//第一个小细节
{
     mid = left + (right - left)/2;//第二个小细节
     if(nums[mid] < target)
        left = mid + 1;
     else
        right = mid;//万恶之源
}

跟普通的二分形式上差不多,到那时有很多的细节要注意。

  1. 循环条件不能写等号!
  2. 求中点操作是偏向左边还是偏向右边,取决于if else语句中哪两边的操作数不一样,就偏向于哪边

因此我们只要发现了二段性,直接套公式即可,下面精讲二段性如何寻找~

例题一:34. 在排序数组中查找元素的第一个和最后一个位置

本题需要求解查找元素的第一个位置(最后一个位置同理),因此我们可以将数组分为

小于元素和大于等于该元素这两个部分。

这里的基准值就是题目中直接给出的target

然后用二分算法求解大于等于这个区间的最左端即可~

例题二:852. 山脉数组的峰顶索引

这里的二段性可以分为,以峰值为区分点,分为两个部分,峰值放在左区间和右区间皆可。

注意这里的基准值是mid跟前一个值或者和后一个值进行比较(方法区分于峰值放在左区间还是右区间)。然后根据峰值在哪个区间求解最值即可。

例题三:162. 寻找峰值

注意该题是完全一个无序的状态,而我们需要的二段性在一个一个小区间中寻找,基准值就是mid坐标和mid前一个值进行比较,因为题目默认-1和n位置上的值都是负无穷,比较结果进行寻找~

例题四:寻找旋转排序数组中的最小值-CSDN博客

本题的基准值是数组的最后一个元素,比较结果可以划分为二段性中的任意一个区间。

例题五:LCR 173. 点名(二分)-CSDN博客

本题的基准值是数组的下标!

总结:

基准值的寻找是不确定的,有可能是题目直接给的值,也有可能是mid前一个数,或者后一个数,或者是数组的最后一个元素,甚至可以是数组自身的下标!

你可能感兴趣的:(算法)