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

lowerBound函数:返回第一个 >= target的数的下标

实现原理:内部是一个while循环,当循环结束时,应当恰好有 left = right 成立,此时right代表 的就是“第一个 >= target的数的下标”————

            - **左阵营 (**`**left**`**)**:在这个索引左边的数,我们确定**全部**都 < target
            - **右阵营 (**`**right**`**)**:在这个索引(包含自身)右边的数,我们确定**全部**都  >= target

又因为target的第一个数恰好满足这个条件,使用lowerBound返回的实际上是target的右边界

之后在主函数中如法炮制,通过求得target+1的首位,再减去1,所得到的就是target的右边界

 1vector<int> searchRange(vector<int>& nums, int target)
 2{
 3    int start = lowerBound(nums, target);
 4    if(start == nums.size() || nums[start] != target)
 5        return {-1, -1};
 6    int end = lowerBound(nums, target + 1) - 1;
 7    return {start, end};
 8}
 9
10// 返回第一个 >= target的数的下标
11int lowerBound(vector<int>& nums, int target)
12{
13    int left = 0, right = nums.size();
14    while(left < right)
15    {
16        int mid = left + (right - left) / 2;
17
18        if(target <= nums[mid])
19            right = mid;
20        else
21            left = mid + 1;
22    }
23    return right;
24}

补充解法:标准库 lower_bound

 1vector<int> searchRange(vector<int>& nums, int target)
 2{
 3    if(nums.empty()) return{-1,-1};
 4
 5    int start = lower_bound(nums.begin(), nums.end(), target) - nums.begin();
 6
 7    if(start == nums.size() || nums[start] != target)
 8        return {-1, -1};
 9
10    // 因为这里得到的是第一个 target + 1 的元素的下标
11    // 所以需要减一得到的才是 target 最后一个元素的下标
12    int end = lower_bound(nums.begin(), nums.end(), target + 1) - nums.begin() - 1;
13    return {start, end};
14}

来源:语雀原笔记