携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
二分
二分思想
二分的思想很简单,就是对于一个有序的数组,要求有序(后一个数大于等于前一个数或是小于等于前一个数)不一定要求单调。
取位置为 mid = (l + r) >> 1 的数判断该数是大于你要找的数x还是小于你要找的数x。如果是大于,就去left去找。如果是小于就去right中去找
整体的思想就这么简单,但是二分难点是在于边界点的处理。对于二分边界点处理方法的不同,把二分分为两个模板
二分模板
橙色点情况
如果是要根据求橙色点值的位置,mid的值有三种情况
①:如果mid的值 < x ,说明mid 的位置在橙色点的左边 l = mid + 1
②:如果mid的值=x,说明mid的位置可能是橙色点,也可能在橙色点左边 l = mid
③:如果mid的值 > x, 说明mid的位置在橙色点右边 r = mid - 1
int bssearch1(int q[], int l, int r, int x){
int mid;
int i = l, j = r;
while(i < j){
mid = (l + r + 1) >> 1;
if(q[mid] <= x) l = mid; //将情况1,2结合
else r = mid - 1;
}
return q[l];
}
蓝色点情况
如果是要根据求蓝色点值的位置,mid的值有三种情况
①:如果mid的值 < x ,说明mid 的位置在蓝色点的左边 l = mid + 1
②:如果mid的值=x,说明mid的位置可能是蓝色点,也可能在蓝色点右边 r = mid
③:如果mid的值 > x, 说明mid的位置在蓝色点右边 r = mid - 1
int bssearch2(int q[], int l, int r, int x){
int mid;
int i = l, j = r;
while(i < j){
mid = (l + r) >> 1;
if(q[mid] >= x) r = mid; //将情况2,3结合
else l = mid + 1;
}
return q[l];
}
注意:橙色点情况,mid值要向上取整。蓝色点情况,mid要向下取整。否则会出现死循环。这块也是二分的难点所在。