
二分查找找到一个target,然后往两侧开始计数
class Solution {
public:
int search(vector<int>& nums, int target) {
int l = 0;
int r = nums.size() - 1;
int pos = -1;
while(l <= r){
int mid = l + ((r - l) >> 1);
if(nums[mid] == target){
// 找到
pos = mid;
break;
}else if(nums[mid] < target){
l = mid + 1;
}else{
r = mid - 1;
}
}
if(pos == -1){
return 0;
}
int cnt = 1;
int left = pos - 1;
while(left >= 0 && nums[left] == target){
cnt++;
left--;
}
int right = pos + 1;
while(right < nums.size() && nums[right] == target){
cnt++;
right++;
}
return cnt;
}
};
我们要知道,当 n u m s [ m i d ] < t a r g e t nums[mid] < target nums[mid]<target时, l l l才会向右移动,也就是说, l l l不可能越过数组中任意一个 t a r g e t target target值。第一次 m i d mid mid指向 t a r g e t target target时,并不退出查找,而是继续循环,直到 l = = r l==r l==r才退出。
由于 l l l不会越过任意一个 t a r g e t target target值, r r r只可能指向不大于 t a r g e t target target的值,我们设定的退出条件是 l = = r l==r l==r,如果数组中存在target,那最终退出时, l l l和 r r r一定指向最左侧的 t a r g e t target target
class Solution {
public:
int search(vector<int>& nums, int target) {
int l = 0;
int r = nums.size() - 1;
int cnt = 0;
while(l < r){
int mid = l + ((r - l) >> 1);
if(nums[mid] >= target){
// 这里mid可能指向target,不能使用r = mid - 1越过当前值
r = mid;
}else{
// 此时的mid小于target,l可以越过mid
l = mid + 1;
}
}
while(l < nums.size() && nums[l] == target){
l++;
cnt++;
}
return cnt;
}
};