lowerBound(下界,第一个 ≥ target 的位置)

int lowerBound(int a[], int n, int target) {
    int left = 0, right = n;
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (a[mid] < target) ___;
        else right = mid;
    }
    return left;
}

填空答案:left = mid + 1

逻辑拆解

  • a[mid] < target:mid位置元素比目标小,答案一定在mid右边,左边界移动到 mid+1
  • a[mid] >= target:答案可能就是mid,或者在mid左边,right = mid

循环结束时 left == right,返回的下标就是第一个大于等于 target 的元素下标

区间是左闭右开 [left, right)right初始等于n,允许返回n(全部元素都小于target的情况)。

例子

a = [1,3,5,7,9]

  1. target = 5 → 返回下标2(a[2]=5)
  2. target = 4 → 返回下标2(a[2]=5,第一个≥4)
  3. target = 10 → 返回下标5(等于n,代表没找到,全部元素更小)

对比 upperBound(第一个 > target 的位置)

int upperBound(int a[], int n, int target) {
    int left = 0, right = n;
    while(left < right){
        int mid = left + (right-left)/2;
        if(a[mid] <= target) left = mid + 1;
        else right = mid;
    }
    return left;
}
函数 条件 含义
lower_bound a[mid] < target → left=mid+1 找第一个 ≥ target
upper_bound a[mid] <= target → left=mid+1 找第一个 > target

记忆口诀: lower:小于就往右走; upper:小于等于就往右走。

思考题:数组[2,4,6,8]lowerBound(a,4,5)返回几?

答案 下标2,a[2]=6,第一个≥5。

⚠️注意:这套是左闭右开模板,和 right=n-1 的闭区间模板不要搞混。C++标准库std::lower_bound就是这套左闭右开逻辑。