正常的 找到target:
迭代:
//二分查找:有则返回该值or序号(看具体情况),找不到则返回-1.
//关键点有三:1、mid = low + (high - low) >> 1 防溢出;2. 注意边界
int binary_search(int* nums, int numsSize, int target){
int low = 0, high = numsSize - 1, mid;//一直猜中间的数。
while(low <= high){
mid = low + (high - low) >> 1;
//使用(low+high)/2会有整数溢出的问题(当low+high的结果大于表达式结果类型所能表示的最大值时)
//这样,产生溢出后再/2是不会产生正确结果的,而low+((high-low)/2)不存在这个问题,666.
if (nums[mid] == target)
return mid;
else if (nums[mid] > target)//猜大了
high = mid - 1;
else
low = mid + 1;
}
if (low > high)
return -1;
}
递归:
int binary_search(int arr[],int low,int high,int key){
int mid = low + (high - low) >> 1;
if(low > high)
return -1;
else{
if(arr[mid] == key)
return mid;
else if (arr[mid] > key)
return binary_search(arr, low, mid - 1, key);
else
return binary_search(arr, mid + 1, high, key);
}
}
特殊的二分查找
如果序列中存在多个所查询的值,返回第一个的位置:
int lowBound(vector<int> &data, int target) {
int low = 0, high = data.size() - 1;
while(low <= high) {
int mid = low + ((high - low) >> 1);
if(data[mid] < target)
low = mid + 1;//low固定在了 target出现的第一个位置后, 就不会再改变! 之后是high在一直减小,low永远不变。下面的upBound同理
else
high = mid - 1;
}
return data[low] == target? low: -1;
}
如果序列中存在多个所查询的值,返回最后一个的位置:
int upBound(vector<int>data, int target) {
int low = 0, high = data.size() - 1, mid;
while(low <= high) {
mid = low + ((high - low) >> 1);
if(data[mid] > target)
high = mid - 1;
else
low = mid + 1;
}
return data[high] == target? high: -1;
}