二分查找
标准的二分查找可以用来查找有序线性表中的值,如果查找成功返回index下表,失败则返回-1.
标准二分查找模板:
int Binary_search(vector<int>& t, int i, int j,int target) {
int left = i, right = j;
int mid=-1 ;
while (left <= right) {
mid = (left + right) / 2;
if (target == t[mid]) {
return mid;//mid为查找到的值的下标
}
else if (target < t[mid]) {
//目标值在左边
right = mid - 1;
}
else{
//目标值在右边
left = mid + 1;
}
}
return -1;
}
进阶
- 若target不存在,查找搜索值左右的下标
例如在vector{1,3,4,5,7}中搜索2(实际不存在)的左右坐标0,1
有没有想过如果查找失败的话,那么最终的left,right指针指向哪?
注意上述代码中的终止条件
while (left <= right)
while结束的时候left>right,假如mid指向target的下标index(实际不存在),那么left会指向target的右侧即index+1,而right指向target的左侧index-1。结论:在二分查找结束后,left=target右侧下标,right=target左侧下标
例如:在vectort={1,3,4,5,7}中查找2的左侧下标和右侧下标,在标准二分模板最后打印left和right的值,
得到left=1,right=0.
- 存在多个target值查找第一个或最后一个target值的下标
例如vectort={1,2,2,3};
简单方法:用二分查找找到其中的一个下标,然后从左或者从右遍历直到最后一个。
进阶方法:直接用二分查找去找target值左边的第一个或者右边的第一个,例中为1,3的坐标
只需要改动if中的判断条件即可。
当target=t[mid]的时候,会继续向[left,mid-1]区间查找,最终查找到的就是target左边的区域啦,由刚刚的结论得知最终的right会指向左侧即target左侧的index。right+1即为第一个target的index。
找最后一个target的下标同理:
将搜索条件改为
最终left-1即为最后一个target的下标。