每日一题:二分查找
二分查找有很多细节,细节中藏着魔鬼
框架是while 加 if
细节在于退出while循环的条件,
空区间,值不存在特殊情况会返回什么。
1.建议对于所有区间使用左闭右开的习惯,即[ left , right ),结束时left一定与right重合
2.取中点时小心值溢出。
学习自知乎 https://www.zhihu.com/question/36132386?sort=created
核心思想是三个区间[ left0,left) [left,right) [ right, right0)
while循环时始终满足
1. 搜索区间[ left, right )不为空 。
2. 搜索区间[ left0 , left )所有元素小于 target
3. 搜索区间[ right, right0) 所有元素大于等于 target
\
最终 left == right, 左边区间中所有值小于 target ,右边区间中所有值大于等于target。
因此返回 left 下标,就是返回第一个出现的target 或者第一个比 target 大的数
一、target左边界的二分查找
int binary( int [] sums, target ) { int left = 0; int right = sums.length; while( left<right ) {mid = left + (right - left) /2; if (sums[mid] < target) left = mid + 1; else right = mid ; } return left; }
返回值的问题
当target不存在时,返回大于的第一项
当target过大时,返回最后一项的后一位(越界问题)
当target过小时,返回第一项
二、STL库函数
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。