当前位置:   article > 正文

边界二分查找_二分查找寻找左边界

二分查找寻找左边界

在这里插入图片描述

左边界的获取索引函数采用low<high,右边界的获取索引函数采用low<=high
具体思路见注释
注意:左边界获取索引要注意向右侧移动后越界
右边界获取索引要注意向左侧移动后越界
两种越界都是一直没找到target导致的
如果找到了第一个满足target的索引,则以此为据点(两种不同边界考虑的算法),找左边界往左移动,找右边界往右移动

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> range;
        range.push_back(searchLeft(nums,target));
        range.push_back(searchRight(nums,target));
        return range;
    }

    int searchLeft(vector<int> & nums, int target){
        if(nums.size()==0){
            return -1;
        }
        int high = nums.size();
        //左闭右开,0-nums.size()-1为有效索引,但是high取size()
        int low = 0;
        int mid = 0;
        while(low < high){
            //当nums[mid] >= target时high向左侧移动
            //左侧边界设定为mid,mid已经比较过,但要保持循环的左闭右开,所以high = mid 
            //直到low == high 时跳出循环 
            //此时high == low && nums[high] == nums[low] == nums[mid] == target
            //当nums[mid] < target时left向右侧移动,mid作为右半部分的左侧边界已经比较过
            //所以新左侧边界依然要保持左闭右开,为low = mid + 1
            //但是可能会出现越界的问题
            //当mid == high - 1 时,此时比较的nums[mid]为nums的最后一个值
            //如果他依然小于target,则low依然会加一,导致low==high,超出了nums的有效索引,此时虽然满足了跳出循环的条件,但是需要返回-1,代表一直到末尾依然没搜索到
            mid = low + ((high - low)>>2);//右移两位要加括号,相当于除以2
            if(nums[mid] == target){
                high = mid;
            }
            else if(nums[mid] < target){
                low = mid + 1;
            }
            else if(nums[mid] > target){
                high = mid;
            }
        }
        if(low == nums.size()){
            return -1;
            //搜索都最右侧,low越界依然没有找到
        }
        return nums[low]==target ? low : -1;
        //若low未越界,则如果它的值等于target,则找到左侧边界的index,否则没找到返回-1
    }
    int searchRight(vector<int> & nums, int target){
        if(nums.size()==0){
            return -1;
        }
        int high = nums.size()-1;
        //左闭右闭,0-nums.size()-1为有效索引
        int low = 0;
        int mid = 0;

        while(low <= high){
            mid = low +((high - low)>>2); 
            if(nums[mid] == target){
                low = mid + 1;
            }
            else if(nums[mid] < target){
                low = mid + 1;
            }
            else if(nums[mid] > target){
                high = mid - 1;
            }
        }
        //一直到最左侧high可能最后减一然后越界
        if(high < 0){
            return -1;
        }
        return nums[high]==target ? high : -1;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/333227
推荐阅读
相关标签
  

闽ICP备14008679号