学习二分有两个境界,第一个境界是见有序用二分,第二个境界是见二段性用二分。
有很多人认为二分只能用于有序的情况下,其实不然,能用二分的前提是具有二段性的特性。
下面主要讲解什么是二段性。
二段性就是可以将数组的数据分为两个部分,这样我们就有mid比较的方式,
注意我们将mid的值跟谁比较才能确定在哪个区间也是很重要的点,也就是寻找与mid比较的基准值!
最终二分出来的结果就是在这两个区间的极值。
while(left < right)//第一个小细节
{
mid = left + (right - left)/2;//第二个小细节
if(nums[mid] < target)
left = mid + 1;
else
right = mid;//万恶之源
}
跟普通的二分形式上差不多,到那时有很多的细节要注意。
因此我们只要发现了二段性,直接套公式即可,下面精讲二段性如何寻找~
本题需要求解查找元素的第一个位置(最后一个位置同理),因此我们可以将数组分为
小于元素和大于等于该元素这两个部分。
这里的基准值就是题目中直接给出的target
然后用二分算法求解大于等于这个区间的最左端即可~
例题二:852. 山脉数组的峰顶索引
这里的二段性可以分为,以峰值为区分点,分为两个部分,峰值放在左区间和右区间皆可。
注意这里的基准值是mid跟前一个值或者和后一个值进行比较(方法区分于峰值放在左区间还是右区间)。然后根据峰值在哪个区间求解最值即可。
例题三:162. 寻找峰值
注意该题是完全一个无序的状态,而我们需要的二段性在一个一个小区间中寻找,基准值就是mid坐标和mid前一个值进行比较,因为题目默认-1和n位置上的值都是负无穷,比较结果进行寻找~
本题的基准值是数组的最后一个元素,比较结果可以划分为二段性中的任意一个区间。
本题的基准值是数组的下标!
基准值的寻找是不确定的,有可能是题目直接给的值,也有可能是mid前一个数,或者后一个数,或者是数组的最后一个元素,甚至可以是数组自身的下标!