二分查找

Search a value

int binarySearch(int []nums,int tar){
    int l=0,r=nums.length-1;
    while(l<=r){
        int mid=l+(r-l)/2;//l+r>>1
        if(nums[mid]==tar) return mid;
        return mid;
        else if(nums[mid]<tar) l=mid+1;
        else if(nums[mid]>tar) r=mid-1;
    }
    return -1;
}

while循环的条件为<=时为闭区间,终止条件为left=right+1

<为左开右闭区间,终止条件为left=right。变成<=只需打个补丁:

while(left<right){
//...
}
return a[left]==target?left:-1;
	  ```
#### 缺陷
nums=\[1,2,2,2,2,2,3] 无法处理,只是找到
### 寻找左侧边界
```c++
   if(nums.length==0) return -1;
   l=0,r=num.length;
   while(l<r)
   //...
   if(nums[mid]==tar) r=mid;
   else if(nums[mid]<tar) l=mid+1;
   else if(nums[mid]>tar) r=mid

   return left;

找到tar后->搜索[left,right).
left 的特殊含义:nums中小于tar的元素有left个,
所以仅需添加

while(l<r){
//...
}//比所有数都大
if(l==nums.length) return -1;
return nums[l]==tar?l:-1;

适用于

  1. 数组有序,包含重复元素
  2. 数组部分有序,不包含重复元素

另一种

对右侧值的收缩更保守

l=0,r=nums.length-1;
while(l<r){
//...
if(nums[mid]<tar) l=mid+1;
else if(nums[mid]>tar) r=mid;
else r--;
}
return nums[l]==tar?l:-1;

寻找右侧边界

//同左侧边界
if(nums[mid]==tar) l=mid+1;
//同左侧边界
/*return l-1;*/
if(l==0) return -1;//l-1
return nums[l-1]==tar?(l-1):-1;

事实上,return left与right 无异;
“当 nums[mid] == target 时,不要立即返回,而是增大「搜索区间」的下界 left,使得区间不断向右收缩,达到锁定右侧边界的目的。”
while 循环结束时,nums[left] 一定不等于 target 了,而 nums[left - 1]可能是target。

二分查找局部极大值

l=0,r=nums.length-1;
while(l<r){
mid=l+((r-l)>>1);
if(nums[mid]<nums[mid+1]) l=mid+1;
else r=mid;
}
return l;

写在后面

查找方式 循环条件 左侧更新 右侧更新 中间点位置 返回值
标准二分查找 left <= right left = mid - 1 right = mid + 1 (left + right) / 2 -1 / mid
二分找左边界 left < right left = mid - 1 right = mid (left + right) / 2 -1 / left
二分找右边界 left < right left = mid right = mid - 1 (left + right) / 2 + 1 -1 / right

二分查找变种

l=0,r=nums.length-1;
while(l<=r){
    if(nums[mid] ? tar) r=mid-1;
    else l=mid+1;
}
return ...;
  1. 判断出是返回left or right:上例中,r=l-1时终止,比较值为tar,查找小于等于(或者是小于)tar的元素,则边界值就是等于key的所有元素的最左边的,返回left。
  2. 判断比较符号:查找小于等于时,用>=此时r=mid-1。

PS:

lower_bound(val) 找的是 x>=val的下界,last则不存在;
upper_bound(val) 找 x>val的下界;
因为区间离散,-1后为对应上界。

posted @ 2022-05-17 18:03  Dustpaw  阅读(70)  评论(0)    收藏  举报