二分法是一种对于有序数列查找时间复杂度为O(logN)的方法。
常见二分法
最常用的方法是找出该数列中是否含有某一个数字,有则返回其位索引,没有则退出返回-1。
while(l<=r){
mid = (l+r)/2;
if(arr[mid]==target){
return mid;
}
if (arr[mid]<target){
l = mid + 1;// 由于除法是向下取整l=mid+1;不然在特定情况下会陷入l=mid的循环
}
else{
r = mid - 1;// r = mid; 是可以的因为只有l=r时才有可能循环
}
}
return -1;
NOTE 1: 如果行1 (l <= r) 改为 (l<r)则会漏掉当l=r且满足条件的情况
二分法找数字的第一个索引位或最后一个索引位
不要在找到时停止,直到遍历到第一个索引位或最后一个索引位,同时如果不存在该数字,则返回不大于该数字的最大元素的索引
int realtwosplit(vector<int> arr, int target, int l_flag) {
int n = arr.size();
int mid, l = 0, r = n - 1;
// find the last one which is not bigger than target; l_flag = 1;
while (l < r) {
mid = (l + r) / 2;
if (arr[mid] >target||l_flag && arr[mid]== target) {
r = mid;//+1;
}
else {
l = mid + 1;
}
}
if (l_flag) {
if (arr[l] <= target) return l;
else return l - 1;
}
else {
if (arr[l] < target && arr[l+1]>target) return l;
else if (arr[l] < target && arr[l + 1] <= target) return l + 1;
else return l - 1;
}
return l;
}
NOTE 2:l_flag作为控制第一索引位的flag