/**
* 范围查询规律
* 初始化:
* int left = 0;
* int right = nums.length - 1;
* 循环条件
* left <= right
* 右边取值
* right = mid - 1
* 左边取值
* left = mid + 1
* 查询条件
* >= target值, 则 nums[mid] >= target时, 都减right = mid - 1
* > target值, 则 nums[mid] > target时, 都减right = mid - 1
* <= target值, 则 nums[mid] <= target时, 都加left = mid + 1
* < target值, 则 nums[mid] < target时, 都加left = mid + 1
* 结果
* 求大于(含等于), 返回left
* 求小于(含等于), 返回right
* 示例(求> 或 >=)
* private int search(int[] nums, int target) {
* int left = 0;
* int right = nums.length - 1;
* while (left <= right){
* int mid = (right - left) / 2 + left;
* if (nums[mid] 查询条件 target){
* right = mid - 1;
* } else {
* left = mid + 1;
* }
* }
* return left(根据查询条件确认);
* }
* 核心思想: 要找某个值, 则查找时遇到该值时, 当前指针(例如right指针)要错过它, 让另外一个指针(left指针)跨过他(体现在left <= right中的=号), 则找到了
*/
作者:chendragon
链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-tong-yong-gui-lu-gu-ding-g93u/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
思路
进行两次二分查找,一次找第一个一次找最后一个
重点:
找第一个:当遇到nums[mid]=target时,将mid赋值给first后继续在mid前面的那个区间找,看有没有更前的,所以将r=mid-1
找最后一个:当遇到nums[mid]=target时,将mid赋值给last后继续在mid后面的那个区间找,看有没有更后的,所以将l=mid+1
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int len=nums.size();
int l=0;
int r=len-1;
// 找第一个位置
int first=-1;
while(l<=r){
int mid=(l+r)/2;
if(target==nums[mid]){
first=mid; // 将mid赋值给first
r=mid-1; // 因为要确保是第一个,所以往前面的区间继续找看还有没有
}
else if(target>nums[mid]){
l=mid+1;
}
else r=mid-1;
}
// 找最后一个位置
int last=-1;
l=0;
r=len-1;
while(l<=r){
int mid=(l+r)/2;
if(target==nums[mid]){
last=mid; // 将mid赋值给last
l=mid+1; // 因为要确保是最后一个,所以往后面的区间继续找看还有没有
}
else if(target>nums[mid]){
l=mid+1;
}
else r=mid-1;
}
if(last>=0){ // 只要不是-1即表示有target在数组中
return vector<int>{first, last};
}
else return vector<int>{-1, -1};
}
};