二分算法
当问题的解具有'二段性'时,可以使用二分算法找出答案。根据待查找区间的中点位置,分析答案会出现在哪一侧,随后舍弃一半的待查找区间,在有答案的区间内继续使用二分查找。时间复杂度为 $O( log N)$。
注意 STL 中的二分查找函数:
lower_bound:返回大于等于 x 的最小元素迭代器,时间复杂度 $O( log N)$。upper_bound:返回大于 x 的最小元素迭代器,时间复杂度 $O( log N)$。
在排序数组中查找元素的第一个和最后一个位置
题目描述
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值,返回 [-1, -1]。
算法思路
核心在于分别寻找左边界和右边界。定义两个指针指向数组的头和尾,通过二分区间缩小范围,并判断获取的端点值是否合法。
二分查找容易陷入死循环,需要注意两点:
- 区间缩小的头尾指针相遇条件。
- 中点的求法(特别是向右取整的情况)。
代码实现
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if (nums.empty()) return {-1, -1};
// 查找左边界
int left = 0, right = nums.size() - 1;
while (left < right) {
int mid = left + (right - left) / 2; // 向下取整
if (nums[mid] >= target) right = mid;
else left = mid + 1;
}
if (nums[left] != target) return {-1, -1};
int retLeft = left;
left = ; right = nums.() - ;
(left < right) {
mid = left + (right - left + ) / ;
(nums[mid] <= target) left = mid;
right = mid - ;
}
{retLeft, right};
}
};


