二分查找——全类型整理

基础:

  给定一个升序数组,找出是否存在目标数target,若存在,则返回下标,若不存在,则返回-1

 

(最万全的写法,int l = 0, r = nums.size(),另外,如果不熟悉,建议if写成三段式,这样最佳)

变式:

1. 找出target数的左边界,若存在,则返回下标,若不存在,则返回-1

2. 找出target数的右边界,若存在,则返回下标,若不存在,则返回-1

 

建议参考leetcode34题,也可部分参考:https://www.cnblogs.com/kyoner/p/11080078.html

 

3. 找出第一个 严格小于 target的数,若存在,则返回下标,若不存在,则返回-1

4. 找出第一个 小于等于 target的数,若存在,则返回下标,若不存在,则返回-1

(其实,3和4是伪命题,仔细想一下,只要判断第一个数字是否满足即可)

5. 找出第一个 严格大于 target的数,若存在,则返回下标,若不存在,则返回-1

6. 找出第一个 大于等于 target的数,若存在,则返回下标,若不存在,则返回-1

 

补充3和4题的解答:

int func(vector<int>& nums, int target) {
    if(nums.empty())
    return -1;

       if(nums[0]<=target) //第4题的答案,如果是要求严格小于,则改成小于符号即可
       return 0;
       else
       return -1;
}

 

5和6题的规律(后文有完整解答):

if(target>nums[mid]) //larger or equal,6题 (如果target都严格大于nums[mid]了,那么左边区间必然不符合条件了)
{
l = mid+1;
}
else
r =mid;

 

// if(target>=nums[mid]) //larger than,5题
// {
// l = mid+1;
// }
// else
// r =mid;

 

第6题的完整解答:

// index of the first number larger or equal than target
int func(vector<int>& nums, int target) {
    int l =0;
    int r = nums.size();
    while(l<r)
    {
        int mid = (r-l)/2+l;
        if(nums[mid]==target)
        r = mid;  //如果是严格大于,则改成 l = mid+1,用于解答第5题
        else if(nums[mid]>target)
        r = mid;
        else if(nums[mid]<target)
        l = mid +1;
    }
    //cout<<l<<endl;
    if(l<nums.size())
    return l;
    else
    return -1;
}

 

第5题的解答:

// index of the first number larger than target
int func(vector<int>& nums, int target) {
    int l =0;
    int r = nums.size();
    while(l<r)
    {
        int mid = (r-l)/2+l;
        if(target>=nums[mid])
        {
            l = mid+1;
        }
        else
        r =mid;
    }
    //cout<<l<<endl;
    if(l<nums.size())
    return l;
    else
    return -1;
}

 

posted @ 2022-01-27 11:42  qiezi_online  阅读(323)  评论(0编辑  收藏  举报