当前位置:   article > 正文

二分查找与边界二分查找(寻找边界)_二分查找边界

二分查找边界

一、普通二分查找

场景描述

普通二分查找只用查找到目标值即可,假定目标只有一个,或者多个目标值只用寻找到一个

过程:

1、设置边界为left<=right

2、设置mid为left和right的中间位置,可任意上下取整

3、若目前的mid大于target,更新right,以缩小查找范围

4、反之目前的mid小于target,更新left,以缩小查找范围

5、若此刻mid刚好等于target,返回mid的下标即可

6,反之,当left>right也没有找到target表示容器内没有target

顺利找到图解:

找不到图解:

二、边界查找 

场景描述:

存在多个target,需要找到target开始位置与结束位置,belike:

过程:

1、分别找左边界和右边界

左边界:

1、将mid向下取整

2、寻找右边界,若当前mid大于或者等于target,更新right=mid

3、若当前mid小于target,更新left=mid+1

4、循环的条件是left<right,即当left==right时,left和right同时指向左边界跳出循环。

右边界:

1、将mid向上取整

2、寻找左边界,若当前mid小于或者等于target,更新left=mid

3、若当前mid大于target,更新right=mid-1

4、循环的条件是left<right,即当left==right时,left和right同时指向右边界跳出循环。

注意细节!!!
1、这里为什么不是更新right=mid-1呢?

答:因为如果当前mid刚好是左边界,如果right=mid-1的话,使得left和right所查找的范围内根本没有target,自然找不到边界值啦

2、为什么左边界需要向上取整右边界需要向下取整呢?

答:图解:

示例题目:力扣:在排序数组中查找元素的第一个和最后一个位置

大家可以试着做一做,答案给大家附上

题目代码:
  1. class Solution {
  2. public:
  3. vector<int> searchRange(vector<int>& nums, int target) {
  4. int n = nums.size();
  5. if (nums.empty()) return { -1,-1 };//为空时的情况
  6. int l = 0, r = n - 1;//初始化并查找左端点
  7. while (l < r)
  8. {
  9. int mid = (l + r) / 2;//向前取mid
  10. if (nums[mid] >= target) r = mid;//找到最左边的端点
  11. else l = mid + 1;
  12. }
  13. if(nums[r]!=target) return { -1,-1 };//若一个target都没有找到
  14. int temp = r;//temp暂存左端点的值
  15. l = 0; r = n - 1;//初始化并查找右端点
  16. while (l < r)
  17. {
  18. int mid = (l + r + 1) / 2;//向后取mid
  19. if (nums[mid]<=target) l = mid;//找到最右边的端点
  20. else r = mid -1;
  21. }
  22. return { temp,r };
  23. }
  24. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/333174
推荐阅读
相关标签
  

闽ICP备14008679号