1. 题目解析
Leetcode链接:34. 在排序数组中查找元素的第一个和最后一个位置

这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。
核心在于找到给定目标值所在的数组下标区间,设计一个O(logn)的算法。
2. 算法原理
寻找左边界思路:
目标:找到数组中第一个大于或等于目标值的元素的索引。
特点:
- 左边区间
[left, resLeft - 1]的所有元素都小于target。 - 右边区间(包括
resLeft)[resLeft, right]的所有元素都大于等于target。
二分查找步骤:
- 初始化
left和right为数组的开始和结束索引。 - 计算中间索引
mid(注意向下取整)。 - 根据
arr[mid]与target的关系,调整left或right的值。- 如果
arr[mid] < target,则更新left = mid + 1。 - 如果
arr[mid] >= target,则更新right = mid。
- 如果
- 重复步骤 2 和 3,直到
left > right。 - 返回
left或right(取决于具体实现)。
注意:当 right = mid 时,应向下取整,以防止死循环。
寻找右边界思路:
目标:找到数组中最后一个大于或等于目标值的元素的索引。
特点:
- 左边区间
[left, resRight]的所有元素都小于等于target。 - 右边区间
[resRight + 1, right]的所有元素都大于target。
二分查找步骤:
- 初始化
left和right为数组的开始和结束索引。 - 计算中间索引
mid(注意向上取整)。 - 根据
arr[mid]与target的关系,调整left或right的值。- 如果
arr[mid] <= target,则更新left = mid。 - 如果
arr[mid] > target,则更新right = mid - 1。
- 如果
- 重复步骤 2 和 3,直到
left > right。 - 返回
right或left(取决于具体实现)。
注意:当 right = mid 时,应向上取整,以防止死循环。
通过合理地调整 left 和 right 的值,二分查找可以高效地找到左边界和右边界。
3. 代码编写
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1, begin = -1, end = -1, mid;
//找到区间左边界
while(left<=right)
{
mid = (left + right)/2;
if(nums[mid] > target)
{
right = mid - 1;
}
else if(nums[mid] < target)
{
left = mid + 1;
}
else
{
begin = mid;
right--;//right区间左移,使得mid左移,直到到达左区间边界,此时right正好和left重合
}
}
left = 0, right = nums.size() - 1;
//找到区间有边界
while(left<=right)
{
mid = (left + right)/2;
if(nums[mid] > target)
{
right = mid - 1;
}
else if(nums[mid] < target)
{
left = mid + 1;
}
else
{
end = mid;
left++;//left区间右移,使得mid右移,直到到达又区间边界,此时left正好和right重合
}
}
return {begin,end};
}
};
The Last
嗯,就是这样啦,文章到这里就结束啦,真心感谢你花时间来读。
觉得有点收获的话,不妨给我点个赞吧!
如果发现文章有啥漏洞或错误的地方,欢迎私信我或者在评论里提醒一声~
![[Docker 教学] 常用的Docker 命令](https://img-blog.csdnimg.cn/direct/a9c4eae43fea463987dc6c59c67ca284.png)


















