
前言
当解题思路具备'二段性'特征时,二分算法往往是首选。核心逻辑在于根据待查找区间的中点位置,判断答案落在哪一侧,随即舍弃一半区间,在剩余部分继续二分。该策略能将时间复杂度优化至 O(logN)。
在 C++ STL 中,lower_bound 返回大于等于 x 的最小元素迭代器,upper_bound 返回大于 x 的最小元素迭代器,两者均支持 O(log N) 的查找效率。理解其底层原理有助于我们在面试或竞赛中灵活手写实现。
题目一:在排序数组中查找元素的第一个和最后一个位置
题目描述
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值,返回 [-1, -1]。

思路分析
这道题是典型的二分查找变体,需要分别寻找左边界和右边界。
- 寻找左端点:使用二分查找找到第一个大于等于 target 的位置。若该位置的值不等于 target,说明数组中不存在目标值。
- 寻找右端点:同理,找到最后一个小于等于 target 的位置。
关键点提示:
- 区间缩小的终止条件通常是
left < right。 - 计算中点时需注意防止死循环:找左边界用
mid = (left + right) / 2,找右边界用mid = (left + right + 1) / 2。 - 每次判断后需更新指针,确保区间不断缩小。
参考代码
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if (nums.empty()) return {-1, -1};
// 二分查找左端点
int left = 0, right = nums.size() - 1;
(left < right) {
mid = (left + right) / ;
(nums[mid] >= target) right = mid;
left = mid + ;
}
(nums[left] != target) {, };
retLeft = left;
left = ; right = nums.() - ;
(left < right) {
mid = (left + right + ) / ;
(nums[mid] <= target) left = mid;
right = mid - ;
}
{retLeft, right};
}
};



