二分查找(模板)

转载自:https://www.jianshu.com/p/0f823fbd4d20

二分查找很好写,却很难写对,出错原因主要集中在判定条件和边界值的选择上,很容易就会导致越界或者死循环的情况。

下面对二分查找及其变形进行总结:

1. 最基本的二分查找

int a[100005];
int find1(int target, int l,int r)//l,r是查找的左右区间
{
    int left = l, right = r, mid;
    while (left <= right)
    {
        mid = left + (right - left) / 2;
        if (a[mid] == target)
            return mid;
        else if (a[mid] > target)
            right = mid - 1;
        else
            left = mid + 1;
    }
    return -1;
}

其中,有几个要注意的点:

  1. 循环的判定条件是:low <= high
  2. 为了防止数值溢出mid = low + (high - low)/2
  3. 当 A[mid]不等于target时,high = mid - 1low = mid + 1

2. 当目标值有多个的时候,返回从左往右的第一个目标值。(目标值区域的左边界/查找与目标值相等的第一个位置/查找第一个不小于目标值数的位置

eg:

A = [1,3,3,5, 7 ,7,7,7,8,14,14]
target = 7
return 4

int a[100005];
int find2(int target,int l,int r) 
{
    int left = l, right = r, mid;
    while (left <= right) 
    {
        mid = left + (right - left) / 2;
        if (target <= a[mid]) 
            right = mid - 1;
        else 
            left = mid + 1;
    }
    if (left <= r && a[left] == target)
        return left;
    else
        return -1;
}

3. 当目标值有多个的时候,返回从左往右的最后一个目标值。(查找目标值区域的右边界/查找与目标值相等的最后一个位置/查找最后一个不大于目标值数的位置

eg:

A = [1,3,3,5,7,7,7, 7 ,8,14,14]
target = 7
return 7

int a[100005];
int find3(int target, int l,int r) 
{
    int left = l, right = r, mid;
    while (left <= right) 
    {
        mid = left + (right - left) / 2;
        if (target >= a[mid]) 
            left = mid + 1;
        else 
            right = mid - 1;
    }
    if (right >= 0 && a[right] == target)
        return right;
    else
        return -1;
}

猜你喜欢

转载自www.cnblogs.com/-citywall123/p/10738597.html
今日推荐